home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / MacApp Release 10 / MacApp Release 10 - HD Ready / Libraries / Framework / Sources / UWindow.cp < prev   
Encoding:
Text File  |  1996-04-03  |  119.6 KB  |  3,982 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UWindow.cp 
  3. // Copyright © 1987-96 by Apple Computer, Inc. All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6. #ifndef __UWINDOW__
  7. #include "UWindow.h"
  8. #endif
  9.  
  10. // MacApp
  11.  
  12. #ifndef __UADORNERS__
  13. #include "UAdorners.h"
  14. #endif
  15.  
  16. #ifndef __UCOREERRORMGR__
  17. #include "UCoreErrorMgr.h"
  18. #endif
  19.  
  20. #ifndef __UCOREGLOBALS__
  21. #include "UCoreGlobals.h"
  22. #endif
  23.  
  24. #ifndef __UCOREUTILITIES__
  25. #include "UCoreUtilities.h"
  26. #endif
  27.  
  28. #ifndef __UCONTAINER__
  29. #include "UContainer.h"
  30. #endif
  31.  
  32. #ifndef __UDEBUG__
  33. #include "UDebug.h"
  34. #endif
  35.  
  36. #ifndef __UDESIGNATOR__
  37. #include "UDesignator.h"
  38. #endif
  39.  
  40. #ifndef __UDIALOGBEHAVIOR__
  41. #include "UDialogBehavior.h"
  42. #endif
  43.  
  44. #ifndef __UDISPATCHER__
  45. #include "UDispatcher.h"
  46. #endif
  47.  
  48. #ifndef __UDOCUMENT__
  49. #include "UDocument.h"
  50. #endif
  51.  
  52. #if qDrag
  53. #ifndef __UDRAGDROP__
  54. #include "UDragDrop.h"
  55. #endif
  56.  
  57. #endif
  58.  
  59. #if qDrag
  60. #ifndef __UDRAGDROPBEHAVIOR__
  61. #include "UDragDropBehavior.h"
  62. #endif
  63.  
  64. #endif
  65.  
  66. #ifndef __UFAILURE__
  67. #include "UFailure.h"
  68. #endif
  69.  
  70. #ifndef __UFILE__
  71. #include "UFile.h"
  72. #endif
  73.  
  74. #ifndef __FLOATWINDOW__
  75. #include "FloatWindow.h"
  76. #endif
  77.  
  78. #if qDrag
  79. #ifndef __ULIST__
  80. #include "UList.h"
  81. #endif
  82.  
  83. #endif
  84.  
  85. #ifndef __UMACAPPGLOBALS__
  86. #include "UMacAppGlobals.h"
  87. #endif
  88.  
  89. #ifndef __UMACAPPUTILITIES__
  90. #include "UMacAppUtilities.h"
  91. #endif
  92.  
  93. #ifndef __UMEMORY__
  94. #include "UMemory.h"
  95. #endif
  96.  
  97. #ifndef __UMENUMGR__
  98. #include "UMenuMgr.h"
  99. #endif
  100.  
  101. #ifndef __UPRINTHANDLER__
  102. #include "UPrintHandler.h"
  103. #endif
  104.  
  105. #ifndef __USCRIPTING__
  106. #include "UScripting.h"
  107. #endif
  108.  
  109. #ifndef __USTREAM__
  110. #include "UStream.h"
  111. #endif
  112.  
  113. // Toolbox
  114.  
  115. #ifndef __AEREGISTRY__
  116. #include <AERegistry.h>
  117. #endif
  118.  
  119. #ifndef __FIXMATH__
  120. #include <FixMath.h>
  121. #endif
  122.  
  123. #ifndef __LOWMEM__
  124. #include <LowMem.h>
  125. #endif
  126.  
  127. #ifndef __RESOURCES__
  128. #include <Resources.h>
  129. #endif
  130.  
  131. #ifndef __TOOLUTILS__
  132. #include <ToolUtils.h>
  133. #endif
  134.  
  135. #ifndef __WINDOWS__
  136. #include <Windows.h>
  137. #endif
  138.  
  139. //CALib
  140. #if qContainer
  141. #ifndef _CALIB_
  142. #include "CALib.h"
  143. #endif
  144.  
  145. #endif
  146.  
  147. enum
  148. {
  149.     kActivateWindow = TRUE, kDeactivateWindow = FALSE
  150. };
  151.  
  152. //========================================================================================
  153. // static data members
  154. //========================================================================================
  155. short TWindow::gStandardWindowStaggerCount;
  156.  
  157. Boolean TWindow::pInBeginUpdate;
  158. GrafPtr TWindow::pInBeginUpdateWindowPtr;
  159. RgnHandle TWindow::pSavedUpdateRegion;
  160. RgnHandle TWindow::pSavedVisRegion;
  161. CPoint TWindow::pSavedVisRegionOriginalOffset;
  162. TDynamicArray* TWindow::gWindows;
  163.  
  164. //========================================================================================
  165. // CLASS TCloseWindowCommand
  166. //========================================================================================
  167. #undef Inherited
  168. #define Inherited TServerCommand
  169.  
  170. #pragma segment MASelCommand
  171. MA_DEFINE_CLASS_M1(TCloseWindowCommand,
  172.                    Inherited);
  173.  
  174. //----------------------------------------------------------------------------------------
  175. // TCloseWindowCommand constructor
  176. //----------------------------------------------------------------------------------------
  177. #pragma segment MASelCommand
  178.  
  179. TCloseWindowCommand::TCloseWindowCommand() :
  180.     fWindow(NULL),
  181.     fMessage(NULL),
  182.     fReply(NULL)
  183. {
  184. }
  185.  
  186. //----------------------------------------------------------------------------------------
  187. // TCloseWindowCommand destructor
  188. //----------------------------------------------------------------------------------------
  189. #pragma segment MADestructorRes
  190.  
  191. TCloseWindowCommand::~TCloseWindowCommand()
  192. {
  193.     // NOTE: We deliberately do not dispose of fMessage and fReply.
  194. }
  195.  
  196. //----------------------------------------------------------------------------------------
  197. // TCloseWindowCommand::ICloseWindowCommand: 
  198. //----------------------------------------------------------------------------------------
  199. #pragma segment MASelCommand
  200.  
  201. void TCloseWindowCommand::ICloseWindowCommand(CommandNumber itsCommandNumber,
  202.                                               TWindow* itsWindow)
  203. {
  204.     TCommandHandler * aContext = itsWindow->GetCommandContext(itsCommandNumber);
  205.  
  206.     ICommand(itsCommandNumber, aContext, kCantUndo, kDoesNotCauseChange, NULL);
  207.  
  208.     fWindow = itsWindow;
  209.  
  210.     //    // If this command is to notify another command then do a link.
  211.     //    if (linkedCommand)
  212.     //        LinkToSecondary(linkedCommand);
  213.  
  214. #if qDebug
  215.     // We should never get a window which has a document attached because we
  216.     // intercept that situation in TWindow's CloseByUser and DoAEClose.
  217.     if (fWindow->fDocument != NULL && fWindow->fClosesDocument)
  218.         ProgramBreak("Attempt to close window which has a document");
  219. #endif
  220. }
  221.  
  222. //----------------------------------------------------------------------------------------
  223. // TCloseWindowCommand::ICloseWindowCommand: 
  224. //----------------------------------------------------------------------------------------
  225. #pragma segment MASelCommand
  226.  
  227. void TCloseWindowCommand::ICloseWindowCommand(TWindow* itsWindow,
  228.                                               TAppleEvent* message,
  229.                                               TAppleEvent* reply)
  230. {
  231.     TCommandHandler * aContext = itsWindow->GetCommandContext(cClose);
  232.     ICommand(cClose, aContext, kCantUndo, kDoesNotCauseChange, NULL);
  233.  
  234.     fWindow = itsWindow;
  235.     fMessage = message;
  236.     fReply = reply;
  237.  
  238.     //    // If this command is to notify another command then do a link.
  239.     //    if (linkedCommand)
  240.     //        LinkToSecondary(linkedCommand);
  241.  
  242. #if qDebug
  243.     // We should never get a window which has a document attached because we
  244.     // intercept that situation in TWindow's CloseByUser and DoAEClose.
  245.     if (fWindow->fDocument != NULL && fWindow->fClosesDocument)
  246.         ProgramBreak("Attempt to close window which has a document");
  247. #endif
  248. }
  249.  
  250. //----------------------------------------------------------------------------------------
  251. // TCloseWindowCommand::MakeAppleEvent: 
  252. //----------------------------------------------------------------------------------------
  253. #pragma segment MACommandRes
  254.  
  255. TAppleEvent* TCloseWindowCommand::MakeAppleEvent()
  256. {
  257.     MAVolatileInit(TAppleEvent * , mayFailEvent, NULL);
  258.     CTempDesc theWindowDesc;
  259.  
  260.     FailInfo fi;
  261.     Try(fi)
  262.     {
  263.         TAppleEvent * theEvent = new TAppleEvent;
  264.         theEvent->IAppleEvent(kAECoreSuite, kAEClose, gServerAddress, kAEWaitReply);
  265.         mayFailEvent = theEvent;
  266.  
  267.         fWindow->MakeObjectSpecifier(theWindowDesc, fWindow->GetSpecifierForm());
  268.         theEvent->WriteParameter(keyDirectObject, theWindowDesc);
  269.  
  270.         // We don't save any of the saving options here because that is done
  271.         // in the TCloseDocument command.
  272.  
  273.         fi.Success();
  274.     }
  275.     else                                        // Recover
  276.     {
  277.         mayFailEvent = (TAppleEvent *)FreeIfObject(mayFailEvent);
  278.         fi.ReSignal();
  279.     }
  280.  
  281.     return mayFailEvent;
  282. }
  283.  
  284. //----------------------------------------------------------------------------------------
  285. // TCloseWindowCommand::DoIt: 
  286. //----------------------------------------------------------------------------------------
  287. #pragma segment MAClose
  288.  
  289. void TCloseWindowCommand::DoIt()
  290. {
  291.     if (fWindow)
  292.     {
  293.         //        FailInfo fi;
  294.         //        Try(fi)
  295.         //        {
  296.         fWindow->CloseAndFree();
  297.         //            fi.Success();
  298.         //        }
  299.         //        else
  300.         //        {
  301.         //            SetValidationError(fi.error);    // In case we are linked.
  302.         //            fi.ReSignal();
  303.         //        }
  304.     }
  305. }
  306.  
  307.  
  308. //========================================================================================
  309. // CLASS TWindow
  310. //========================================================================================
  311. #undef Inherited
  312. #define Inherited TView
  313.  
  314. #pragma segment MAOpen
  315. MA_DEFINE_CLASS_M2(TWindow,
  316.                    Inherited,
  317.                    MScriptableObject);
  318.  
  319. //----------------------------------------------------------------------------------------
  320. // TWindow Constructor.
  321. //----------------------------------------------------------------------------------------
  322. #pragma segment MAOpen
  323.  
  324. TWindow::TWindow() :
  325.     MScriptableObject(cWindow),
  326.  
  327.     // We can't tell if any changing will be required so we just the fMustxxx these false here. If
  328.     // the developer sets them true then we respect them or if the developer calls the
  329.     // corresponding functions we set them.
  330.     fMoveBounds(gZeroRect),                        // gZeroRect indicates dynamic (the default)
  331.     fResizeLimits(gZeroRect),                    // gZeroRect indicates dynamic (the default)
  332.     fContentDifference(gZeroPt),
  333.     fContentRegionInset(gZeroPt),
  334.     fScriptingPrintHandler(NULL),
  335.     fTarget(this),
  336.     fWMgrWindow(NULL),
  337.     fTargetID(fIdentifier),
  338.     fProcID(0),
  339.     fPreDocname(0),
  340.     fConstTitle(0),
  341.     fStrListID(kNoResource),                    // window's title:    STR# rsrc id
  342.     fIndex(kNoResource),                        //                    index into STR#
  343.     fUpdating(FALSE),
  344.     fIsActive(FALSE),
  345.     fIsResizable(TRUE),
  346.     fIsClosable(TRUE),
  347.     fFreeOnClosing(FALSE),
  348.     fDisposeOnFree(TRUE),
  349.     fClosesDocument(TRUE),
  350.     fOpenInitially(TRUE),
  351.     fDoFirstClick(FALSE),
  352.     fFloats(FALSE),
  353.     fHideOnSuspend(FALSE),
  354.     fWasHiddenOnSuspend(FALSE),
  355.     fGenerateActivates(TRUE),
  356.  
  357.     fMustAdapt(FALSE),
  358.     fMustHorzCenter(FALSE),
  359.     fMustVertCenter(FALSE),
  360.     fMustStagger(FALSE),
  361.     fMustForceOnScreen(FALSE),
  362.  
  363.     fAdapted(FALSE),                            // Set by AdaptToScreen
  364.     fHorzCentered(FALSE),                        // Set by Center 
  365.     fVertCentered(FALSE),                        // Set by Center 
  366.     fStaggered(FALSE),                            // Set by SimpleStagger 
  367.     fForcedOnScreen(FALSE)                        // Set by ForceOnScreen 
  368.  
  369. #if qDrag
  370.     ,
  371.     fDroppableViewList(NULL),                    // Drag and Drop data
  372.     fDropStatusCache(NULL),
  373.     fDragCallbackStatus(eWindowNotInited)
  374. #endif // qDrag        
  375.  
  376. {
  377. }
  378.  
  379. //----------------------------------------------------------------------------------------
  380. // TWindow::IWindow: 
  381. //----------------------------------------------------------------------------------------
  382. #pragma segment MAOpen
  383.  
  384. void TWindow::IWindow(TDocument* itsDocument,
  385.                       WindowRef itsWMgrWindow,
  386.                       Boolean canResize,
  387.                       Boolean canClose,
  388.                       Boolean disposeOnFree)
  389. {
  390. #if qDebug
  391.     if (!itsWMgrWindow)
  392.     {
  393. #if qDebugMsg
  394.         ProgramBreak("TWindow::IWindow requires a valid WindowRef!");
  395. #endif
  396.  
  397.         Free();
  398.         Failure(minErr, 0);
  399.     }
  400. #endif
  401.  
  402.     MAVolatileInit(WindowRef, volatileItsWMgrWindow, itsWMgrWindow);
  403.     MAVolatileInit(Boolean, volatileDisposeOnFree, disposeOnFree);
  404.  
  405.     //MAVolatile(GrafPtr, savePort);
  406.     GrafPtr savePort;                            // can't be volatile because it is passed by reference
  407.     GetPort(&savePort);
  408.  
  409.     CPoint itsLocation = ((CRect &)GetWindowPort(volatileItsWMgrWindow)->portRect)[topLeft];
  410.     SetPortWindowPort(volatileItsWMgrWindow);    // So LocalToGlobal works 
  411.     LocalToGlobal(&itsLocation);
  412.  
  413.     VPoint portSize(((CRect &)GetWindowPort(volatileItsWMgrWindow)->portRect).GetSize());
  414.     FailInfo fi1;
  415.     Try(fi1)
  416.     {
  417.         IView(itsDocument, NULL, itsLocation, portSize, sizeVariable, sizeVariable);
  418.         fi1.Success();
  419.     }
  420.     else                                        // Recover
  421.     {
  422.         SetPort(savePort);
  423.         volatileItsWMgrWindow = FreeIfWMgrWindow(volatileItsWMgrWindow, volatileDisposeOnFree);
  424.         fi1.ReSignal();
  425.     }
  426.  
  427.     // Initialize instance variables.
  428.     fWMgrWindow = volatileItsWMgrWindow;
  429.     fDisposeOnFree = volatileDisposeOnFree;
  430.  
  431.     ResNumber itsID = 0;
  432.     Handle theWDEFProc = WindowPeek(volatileItsWMgrWindow)->windowDefProc;
  433.     if (IsAResource(theWDEFProc))
  434.     {
  435.         ResType itsType;
  436.         CStr255 itsName;
  437.  
  438.         GetResInfo(theWDEFProc, &itsID, &itsType, itsName);
  439.     }
  440.     fProcID = (itsID << 4) | GetWindowVariant(fWMgrWindow);
  441.  
  442.     fIsResizable = canResize;
  443.  
  444.     FailInfo fi2;
  445.     Try(fi2)
  446.     {
  447.         if (canResize)
  448.             AddAdorner(gResizeIconAdorner, kAdornLast, FALSE);
  449.         fIsClosable = canClose;
  450.         BuildWindowRegions(BuildWindowRegions(kBuild));// sets fContentRegionInset && fContentDifference 
  451.  
  452.         // don't use the GetResizeLimits accessor b/c we want to preserve zero values for dynamics
  453.         SetResizeLimits(fResizeLimits[topLeft], fResizeLimits[botRight]);
  454.  
  455.         CStr255 aString;
  456.         GetTitle(aString);
  457.  
  458.         short preDocname;
  459.         short constTitle;
  460.         if (ParseTitleTemplate(aString, preDocname, constTitle))
  461.             SetWTitle(fWMgrWindow, aString);
  462.         fPreDocname = preDocname;
  463.         fConstTitle = constTitle;
  464.  
  465.         if (itsDocument)
  466.         {
  467.             itsDocument->GetTitle(aString);
  468.             if (!aString.IsEmpty())                // not an untitled document 
  469.                 SetTitleForDoc(aString);
  470.         }
  471.  
  472.         AddAdorner(gEraseAdorner, kAdornFirst, FALSE);
  473.  
  474.         RegisterWindow(this);                    // add to the lookup table
  475.  
  476.         fi2.Success();
  477.     }
  478.     else                                        // Recover
  479.     {
  480.         SetPort(savePort);
  481.         Free();
  482.         fi2.ReSignal();
  483.     }
  484. }
  485.  
  486. //----------------------------------------------------------------------------------------
  487. // TWindow::Clone:
  488. //----------------------------------------------------------------------------------------
  489. #pragma segment MAWindowNonRes
  490.  
  491. TObject* TWindow::Clone()                        // override 
  492. {
  493.     MAVolatileInit(TWindow * , aClonedWindow, (TWindow *)Inherited::Clone());
  494.  
  495.     if (aClonedWindow->fWMgrWindow != NULL)
  496.     {
  497.         MAVolatileInit(Boolean, oldPerm, PermAllocation(FALSE));
  498.  
  499.         aClonedWindow->fWMgrWindow = NULL;
  500.  
  501.         FailInfo fi;
  502.         Try(fi)
  503.         {
  504.             CRect boundsRect(GetWindowPort(fWMgrWindow)->portRect);
  505.  
  506.             WindowRef behind;
  507.             if (IsModal())
  508.                 behind = (WindowRef) - 1;
  509.             else
  510.                 behind = GetBehindWindowPtr();
  511.  
  512.             CStr255 windowTitle;
  513.             GetTitle(windowTitle);
  514.  
  515.             long windowRefCon = GetWRefCon(fWMgrWindow);
  516.  
  517.             WindowRef aWMgrWindow;
  518.             if (qNeedsColorQD || HasColorQD())
  519.             {
  520.                 WindowRef storage = NULL;
  521. #if !STRICT_WINDOWS
  522.                 storage = (WindowRef)new CWindowRecord;
  523. #endif
  524.  
  525.                 aWMgrWindow = NewCWindow(storage, &boundsRect, windowTitle, FALSE, fProcID, behind, fIsClosable, windowRefCon);
  526.             }
  527.             else
  528.             {
  529.                 WindowRef storage = NULL;
  530. #if !STRICT_WINDOWS
  531.                 storage = (WindowRef)new WindowRecord;
  532. #endif
  533.  
  534.                 aWMgrWindow = NewWindow(storage, &boundsRect, windowTitle, FALSE, fProcID, behind, fIsClosable, windowRefCon);
  535.             }
  536.             aClonedWindow->fWMgrWindow = aWMgrWindow;
  537.             FailNIL(aWMgrWindow);
  538.  
  539.             oldPerm = PermAllocation(oldPerm);
  540.             fi.Success();
  541.         }
  542.         else
  543.         {
  544.             aClonedWindow->Free();
  545.             oldPerm = PermAllocation(oldPerm);
  546.             fi.ReSignal();
  547.         }
  548.     }
  549.  
  550.     return aClonedWindow;
  551. }
  552.  
  553. //----------------------------------------------------------------------------------------
  554. // TWindow::DoPostCreate: 
  555. //----------------------------------------------------------------------------------------
  556. #pragma segment DlgOpen
  557.  
  558. void TWindow::DoPostCreate(TDocument* itsDocument)// Override
  559. {
  560.     Inherited::DoPostCreate(itsDocument);
  561.  
  562.     // don't use the GetResizeLimits accessor b/c we want to preserve zero values for dynamics
  563.     SetResizeLimits(fResizeLimits[topLeft], fResizeLimits[botRight]);
  564.     BuildWindowRegions(BuildWindowRegions(kBuild));// sets fContentRegionInset && fContentDifference
  565.  
  566. #if qDrag
  567.     fDragCallbackStatus = eNotInstalled;
  568.  
  569.     if (HasDragManager() && fDroppableViewList &&// If subviews have registered
  570.         !fDroppableViewList->IsEmpty())            // then register the window with the drag session
  571.     {
  572.         TDragDropSession::fgDragDropSession->RegisterDroppableWindow(this, fWMgrWindow);
  573.         fDragCallbackStatus = eInstalled;
  574.     }
  575. #endif // qDrag
  576. }
  577.  
  578. //----------------------------------------------------------------------------------------
  579. // TWindow::GetBehindWindowPtr: 
  580. //----------------------------------------------------------------------------------------
  581. #pragma segment MAOpen
  582.  
  583. WindowRef TWindow::GetBehindWindowPtr()
  584. {
  585.     WindowRef behind = GetLastFloatingWindowPtr();
  586.     if (!behind)
  587.         behind = (WindowRef)(-1);                // bring the window up in front of all other windows
  588.  
  589.     return behind;
  590. }
  591.  
  592. //----------------------------------------------------------------------------------------
  593. // TWindow::GetDialogBehavior: 
  594. //----------------------------------------------------------------------------------------
  595. #pragma segment MAWindowRes
  596.  
  597. TDialogBehavior* TWindow::GetDialogBehavior()
  598. {
  599.     return (TDialogBehavior *)GetBehaviorWithIdentifier(kDialogBehavior);
  600. }
  601.  
  602. //----------------------------------------------------------------------------------------
  603. // TWindow::SetModality: 
  604. //----------------------------------------------------------------------------------------
  605. #pragma segment MAOpen
  606.  
  607. void TWindow::SetModality(Boolean modal)
  608. {
  609.     TDialogBehavior * itsDialogBehavior = GetDialogBehavior();
  610.  
  611.     if (itsDialogBehavior)
  612.         itsDialogBehavior->fModal = modal;
  613.     else
  614.     {
  615.         if (modal)
  616.         {
  617.             // Allocate the behavior from temporary memory in case we are trying to warn
  618.             // the user about something.  We shouldn't fail here.
  619.             Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  620.             itsDialogBehavior = new TDialogBehavior;
  621.             AllocateObjectsFromPerm(oldObjectPerm);
  622.             itsDialogBehavior->IDialogBehavior(modal, kNoIdentifier, kNoIdentifier);
  623.             AddBehavior(itsDialogBehavior);
  624.         }
  625.     }
  626. }
  627.  
  628. //----------------------------------------------------------------------------------------
  629. // TWindow::SetDialogItems: 
  630. //----------------------------------------------------------------------------------------
  631. #pragma segment MAOpen
  632.  
  633. void TWindow::SetDialogItems(IDType itsDefaultItem,
  634.                              IDType itsCancelItem)
  635. {
  636.     TDialogBehavior * itsDialogBehavior = GetDialogBehavior();
  637.  
  638.     if (itsDialogBehavior)
  639.     {
  640.         itsDialogBehavior->fDefaultItem = itsDefaultItem;
  641.         itsDialogBehavior->fCancelItem = itsCancelItem;
  642.     }
  643.     else
  644.     {
  645.         if ((itsDefaultItem != kNoIdentifier) || (itsCancelItem != kNoIdentifier))
  646.         {
  647.             // Allocate the behavior from temporary memory in case we are trying to warn
  648.             // the user about something.  We shouldn't fail here.
  649.             Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  650.             itsDialogBehavior = new TDialogBehavior;
  651.             AllocateObjectsFromPerm(oldObjectPerm);
  652.             itsDialogBehavior->IDialogBehavior(FALSE, itsDefaultItem, itsCancelItem);
  653.             AddBehavior(itsDialogBehavior);
  654.         }
  655.     }
  656. }
  657.  
  658. //----------------------------------------------------------------------------------------
  659. // TWindow::Free: 
  660. //----------------------------------------------------------------------------------------
  661. #pragma segment MAClose
  662.  
  663. TWindow::~TWindow()
  664. {
  665.     Boolean disposeOnFree = fDisposeOnFree;
  666.     WindowRef wmgrWindow = fWMgrWindow;
  667.  
  668. #if qDrag
  669.     if (HasDragManager() && fDragCallbackStatus == eInstalled)// remove drag manager callbacks
  670.     {
  671.         TDragDropSession::fgDragDropSession->UnregisterDroppableWindow(fWMgrWindow);
  672.         fDragCallbackStatus = eNotInstalled;
  673.     }
  674.  
  675.     fDroppableViewList = (TList *)FreeIfObject(fDroppableViewList);
  676.     fDropStatusCache = (TDynamicArray *)FreeIfObject(fDropStatusCache);
  677. #endif // qDrag
  678.  
  679.     DeleteWindow(this);                            // remove from the lookup table
  680.     fWMgrWindow = NULL;
  681.     BeInPort(NULL);                                // make sure subviews don't depend on the window manager window
  682.  
  683.     if (fDocument)
  684.         fDocument->DeleteWindow(this);
  685.     else
  686.         gDispatcher->DeleteWindow(this);
  687.  
  688.     wmgrWindow = FreeIfWMgrWindow(wmgrWindow, disposeOnFree);
  689. }
  690.  
  691. //----------------------------------------------------------------------------------------
  692. // TWindow::GetStandardSignature: 
  693. //----------------------------------------------------------------------------------------
  694. #pragma segment MAWriteResource
  695.  
  696. IDType TWindow::GetStandardSignature()            // override 
  697. {
  698.     return kStdWindow;
  699. }
  700.  
  701. //----------------------------------------------------------------------------------------
  702. // TWindow::ReadFields: 
  703. //----------------------------------------------------------------------------------------
  704. #pragma segment MAReadResource
  705.  
  706. void TWindow::ReadFields(TStream* aStream)        // override 
  707. {
  708.     Inherited::ReadFields(aStream);
  709.  
  710.     WindowFlags itsFlags;
  711.  
  712.     FailInfo fi;
  713.     Try(fi)
  714.     {
  715.         CStr255 title;
  716.         VRect bounds(GetFrame());
  717.  
  718.         fProcID = aStream->ReadInteger();
  719.  
  720.         fTargetID = aStream->ReadIDType();
  721.  
  722.         aStream->ReadBytes(&itsFlags, sizeof(WindowFlags));
  723.  
  724.         fStrListID = aStream->ReadInteger();
  725.         fIndex = aStream->ReadInteger();
  726.         if (fStrListID != kNoResource)            // retrieve the window's title from the resource
  727.             GetIndString(title, fStrListID, fIndex);
  728.  
  729.         WindowRef behind;
  730.         if (IsModal())
  731.             behind = (WindowRef) - 1;
  732.         else
  733.             behind = GetBehindWindowPtr();
  734.  
  735.         // Compatibility Floating WDEF support. We will
  736.         // use the WDEF specified by this ID if we are not
  737.         // running on System 7.5 or better. If we are, however,
  738.         // we will change the ID dynamically in the window
  739.         // initialization sequence. This ensures that we use
  740.         // the WDEF stored in your program on pre System 7.5
  741.         // but, use the WDEF stored in the system thereafter.        
  742.  
  743.         // top 12 bits identify the WDEF, bottom 4 bits are the style
  744.         short procID = fProcID;                    // default
  745.         if (qNeedsSystem7_5 || GetSystemVersion() >= 0x750)
  746.             if ((fProcID & 0xFFF0) == kSystem75AndLess_kWindoidWDEF)
  747.                 procID = kSystem75_kWindoidWDEF | (fProcID & 0x000F);
  748.  
  749.         WindowRef aWMgrWindow;
  750.         CRect theBounds = bounds.ToRect();
  751.         if (qNeedsColorQD || HasColorQD())
  752.             aWMgrWindow = (WindowRef)NewCWindow(NULL, &theBounds, title, FALSE, procID, behind, itsFlags.GetHasGoAway(), ((long)this));
  753.         else
  754.             aWMgrWindow = NewWindow(NULL, &theBounds, title, FALSE, procID, behind, itsFlags.GetHasGoAway(), ((long)this));
  755.         fWMgrWindow = aWMgrWindow;
  756.  
  757.         fIsResizable = itsFlags.GetResizable();
  758.         fIsClosable = itsFlags.GetHasGoAway();
  759.         fDoFirstClick = itsFlags.GetDoFirstClick();
  760.         fFreeOnClosing = itsFlags.GetFreeOnClosing();
  761.         fDisposeOnFree = itsFlags.GetDisposeOnFree();
  762.         fClosesDocument = itsFlags.GetClosesDocument();
  763.         fOpenInitially = itsFlags.GetOpenInitially();
  764.  
  765.         GetTitle(title);
  766.  
  767.         short preDocname;
  768.         short constTitle;
  769.         if (ParseTitleTemplate(title, preDocname, constTitle))
  770.             SetWTitle(fWMgrWindow, title);
  771.         fPreDocname = preDocname;
  772.         fConstTitle = constTitle;
  773.  
  774.         RegisterWindow(this);                    // add to the lookup table
  775.  
  776.         fi.Success();
  777.     }
  778.     else                                        // Recover
  779.     {
  780.         Free();
  781.         fi.ReSignal();
  782.     }
  783.  
  784.     fMustAdapt = itsFlags.GetMustAdaptToScreen();
  785.     fMustStagger = itsFlags.GetStagger();
  786.     fMustForceOnScreen = itsFlags.GetMustForceOnScreen();
  787.     fMustHorzCenter = itsFlags.GetHorzCenter();
  788.     fMustVertCenter = itsFlags.GetVertCenter();
  789.     fFloats = itsFlags.GetFloats();
  790.  
  791.     fHideOnSuspend = itsFlags.GetHideOnSuspend();
  792.     fGenerateActivates = itsFlags.GetGenerateActivates();
  793. }
  794.  
  795. //----------------------------------------------------------------------------------------
  796. // TWindow::WriteFields: 
  797. //----------------------------------------------------------------------------------------
  798. #pragma segment MAWriteResource
  799.  
  800. void TWindow::WriteFields(TStream* aStream)        // override 
  801. {
  802.     Inherited::WriteFields(aStream);
  803.  
  804.     aStream->WriteInteger(fProcID);
  805.     aStream->WriteIDType(fTargetID);
  806.  
  807.     WindowFlags itsFlags;
  808.  
  809.     itsFlags.Initialize();
  810.     itsFlags.SetHasGoAway(fIsClosable);
  811.     itsFlags.SetResizable(fIsResizable);
  812.     itsFlags.SetDoFirstClick(fDoFirstClick);
  813.     itsFlags.SetFreeOnClosing(fFreeOnClosing);
  814.     itsFlags.SetDisposeOnFree(fDisposeOnFree);
  815.     itsFlags.SetClosesDocument(fClosesDocument);
  816.     itsFlags.SetOpenInitially(fOpenInitially);
  817.     itsFlags.SetMustAdaptToScreen(fMustAdapt);
  818.     itsFlags.SetStagger(fMustStagger);
  819.     itsFlags.SetMustForceOnScreen(fMustForceOnScreen);
  820.     itsFlags.SetVertCenter(fMustVertCenter);
  821.     itsFlags.SetHorzCenter(fMustHorzCenter);
  822.     itsFlags.SetFloats(fFloats);
  823.     itsFlags.SetHideOnSuspend(fHideOnSuspend);
  824.     itsFlags.SetGenerateActivates(fGenerateActivates);
  825.  
  826.     // write the flags
  827.     aStream->WriteBytes(&itsFlags, sizeof(WindowFlags));
  828.  
  829.     // write the window title
  830.     aStream->WriteInteger(fStrListID);
  831.     aStream->WriteInteger(fIndex);
  832. }
  833.  
  834. //----------------------------------------------------------------------------------------
  835. // TWindow::Activate: 
  836. //----------------------------------------------------------------------------------------
  837. #pragma segment MAActivate
  838.  
  839. void TWindow::Activate(Boolean entering)
  840. {
  841.     Boolean different = (entering != IsActive());
  842.     if (different)
  843.     {
  844.         // Change to allow floating windows to be activated even if there is an
  845.         // active document window around. 
  846.         if (entering && !fFloats)
  847.         {
  848.             // make sure that there is not already an active window - we
  849.             // can't have two active ones at the same time (note that code outside
  850.             // MacApp might call SelectWindow and generate activate events for windows
  851.             // that really are not active, so we have to catch this possibility)…
  852.             CWMgrIterator iter;
  853.             TWindow * theMAWindow = NULL;
  854.  
  855.             for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  856.             {
  857.                 if ((theMAWindow = WMgrToWindow(aWindowPtr)) != NULL)
  858.                     if (theMAWindow->IsActive() && !IsFloatWindow(aWindowPtr))
  859.                         return;                    // someone else is active - bail out!
  860.             }
  861.         }
  862.  
  863.         Inherited::Activate(entering);
  864.  
  865.         fIsActive = entering;
  866.  
  867. #if FALSE
  868.         // The following block implements a new style of target management for
  869.         // floating window support that was (temporarily) introduced for MacApp 3.1.
  870.         // Because of the reaction from MacApp developers, we have reverted to
  871.         // MacApp 3.0.1's style of handling activation.  This block has been left in
  872.         // the MacApp source because the jury is still out on how best to handle
  873.         // the situation where a floater wants to be the target…
  874.  
  875.         TWindow * windowOfTarget = NULL;
  876.         if (gDispatcher->GetTarget() != NULL)
  877.             windowOfTarget = gDispatcher->GetTarget()->GetWindow();
  878.         Boolean targetInFloatingWindow = windowOfTarget != NULL && windowOfTarget->fFloats;
  879.  
  880.         // if the target is in a floating window, leave it alone!
  881.         if (!targetInFloatingWindow)
  882.             if (entering)
  883.                 gDispatcher->SetTarget(fTarget);
  884.             else
  885.                 gDispatcher->SetTarget(gDispatcher);
  886. #endif
  887.  
  888.         // The original, MacApp 3.0.1 technique:
  889.         if (!(fFloats && (fTarget == this)))
  890.             if (entering)
  891.                 gDispatcher->SetTarget(fTarget);
  892.             else
  893.                 gDispatcher->SetTarget(gDispatcher);
  894.  
  895.         // When we de/activate a window, we need to invalidate the menus manually here.
  896.         // Because we no longer receive activate/deactivates regularly from the Event
  897.         // Manager, we cannot count on TApplication::DidEvent to handle this for us…
  898.         InvalidateMenus();
  899.     }
  900. }
  901.  
  902. //----------------------------------------------------------------------------------------
  903. // TWindow::AdaptToScreen: 
  904. //----------------------------------------------------------------------------------------
  905. #pragma segment MAOpen
  906.  
  907. void TWindow::AdaptToScreen()
  908. {
  909.     long stdHScreen = 512;                        // make these longs for Long2Fix call
  910.     long stdVScreen = 342;
  911.  
  912.     fAdapted = TRUE;                            // We adapted to the screen 
  913.  
  914.     // Compute pixel difference between current screen and std Mac screen Note:
  915.     // Calculation written as two separate expressions so that CPoint's "-" operator can
  916.     // be inline.
  917.     VPoint diff(((CRect &)qd.screenBits.bounds).GetSize());
  918.     diff -= VPoint(stdHScreen, stdVScreen);
  919.  
  920.     VRect theFrame(GetFrame());
  921.  
  922.     // If screen is larger, enlarge the window. If the window is too large, shrink it 
  923.     if (diff != gZeroVPt || !((CRect &)qd.screenBits.bounds).Contains(theFrame[botRight].ToPoint()))
  924.     {
  925.         // do an adjustment for larger screen
  926.         // the window adapted to the new screen size by proportion. 
  927.         VPoint newSize(Fix2Long(FixMul(Long2Fix(fSize.h), FixDiv(Long2Fix(stdHScreen + diff.h), Long2Fix(stdHScreen)))), Fix2Long(FixMul(Long2Fix(fSize.v), FixDiv(Long2Fix(stdVScreen + diff.v), Long2Fix(stdVScreen)))));
  928.  
  929.         // Consider the location of the window, bound it by the resize limits 
  930.         CRect resizeLimits;
  931.         GetDynamicResizeLimits(resizeLimits);
  932.  
  933.         newSize.ConstrainTo(resizeLimits);
  934.         Resize(newSize, kInvalidate);
  935.     }
  936. }
  937.  
  938. //----------------------------------------------------------------------------------------
  939. // TWindow::AllowsMenuAccess: 
  940. //----------------------------------------------------------------------------------------
  941. #pragma segment MAWindowRes
  942.  
  943. Boolean TWindow::AllowsMenuAccess()
  944. {
  945.     // Default is to always allow menu access, even if modal 
  946.     return TRUE;
  947. }
  948.  
  949.  
  950. typedef WindowDefProcPtr* WDefProcTypeHandle;
  951.  
  952. //----------------------------------------------------------------------------------------
  953. // TWindow::Center: 
  954. //----------------------------------------------------------------------------------------
  955. #pragma segment MAOpen
  956.  
  957. void TWindow::Center(Boolean horizontally,
  958.                      Boolean vertically,
  959.                      Boolean forDialog)
  960. {
  961.     if (fWMgrWindow)
  962.     {
  963.         fHorzCentered = horizontally;
  964.         fVertCentered = vertically;
  965.  
  966.         Boolean rgnsWereBuilt = BuildWindowRegions(kBuild);
  967.         CTemporaryRegion strucRgn;
  968.         GetWindowStructureRgn(fWMgrWindow, strucRgn);
  969.         CPoint windowSize(((CRect &)(*strucRgn)->rgnBBox).GetSize());
  970.         BuildWindowRegions(rgnsWereBuilt);
  971.  
  972.         VRect theFrame(GetFrame());
  973.  
  974.         // GetMaxIntersectedDevice accounts for menubar so don't subtract GetMBarHeight
  975.         CRect screenRect;
  976.         GetMaxIntersectedDevice(screenRect);
  977.         CPoint screenSize = screenRect.GetSize();
  978.  
  979.         if (horizontally)
  980.             theFrame.left = screenRect.left + fContentRegionInset.h + (screenSize.h - windowSize.h) / 2;
  981.  
  982.         if (vertically)
  983.         {
  984.             if (forDialog)
  985.             // Put it in the top third of the screen 
  986.                 theFrame.top = screenRect.top + fContentRegionInset.v + (screenSize.v - windowSize.v) / 3;
  987.             else
  988.                 theFrame.top = screenRect.top + fContentRegionInset.v + (screenSize.v - windowSize.v) / 2;
  989.         }
  990.  
  991.         Locate(theFrame[topLeft], kDontInvalidate);
  992.     }
  993. }
  994.  
  995. //----------------------------------------------------------------------------------------
  996. // TWindow::Close: 
  997. //----------------------------------------------------------------------------------------
  998. #pragma segment MAClose
  999.  
  1000. void TWindow::Close()                            // override 
  1001. {
  1002.     Inherited::Close();
  1003.  
  1004.     Show(FALSE, kRedraw);
  1005. }
  1006.  
  1007. //----------------------------------------------------------------------------------------
  1008. // TWindow::CloseAndFree: 
  1009. //----------------------------------------------------------------------------------------
  1010. #pragma segment MAClose
  1011.  
  1012. void TWindow::CloseAndFree()
  1013. {
  1014.     Close();
  1015.     if (fFreeOnClosing)
  1016.         Free();
  1017. }
  1018.  
  1019. //----------------------------------------------------------------------------------------
  1020. // TWindow::CloseByUser: 
  1021. //----------------------------------------------------------------------------------------
  1022. #pragma segment MAClose
  1023.  
  1024. void TWindow::CloseByUser(CommandNumber aCommandNumber)
  1025. {
  1026.     // First see if the document is to be closed.
  1027.     if (fDocument)
  1028.     {
  1029.         // Allow the document to determine the proper response to
  1030.         // closing one of its windows.
  1031.         fDocument->CloseWindow(this);
  1032.     }
  1033.     else
  1034.     {
  1035.         // Close the window directly since it wasn't attached to a document.
  1036.         DoClose(aCommandNumber);
  1037.     }
  1038. }
  1039.  
  1040. //----------------------------------------------------------------------------------------
  1041. // TWindow::DoClose: 
  1042. //----------------------------------------------------------------------------------------
  1043. #pragma segment MAClose
  1044. void TWindow::DoClose(CommandNumber aCommand,
  1045.                       Boolean useAppleEvent)
  1046. {
  1047.     // Close the window if it wasn't attached to a document.
  1048.     Boolean oldTempAlloc = TemporaryAllocation(TRUE);
  1049.     Boolean oldObjectPerm = AllocateObjectsFromPerm(FALSE);
  1050.     TCloseWindowCommand * aCloseWindowCommand = new TCloseWindowCommand;
  1051.     aCloseWindowCommand->ICloseWindowCommand(aCommand, this);
  1052.     aCloseWindowCommand->fUseAppleEvent = useAppleEvent;
  1053.  
  1054.     if (useAppleEvent)
  1055.         PostCommand(aCloseWindowCommand);
  1056.     else
  1057.         aCloseWindowCommand->Process();
  1058.  
  1059.     TemporaryAllocation(oldTempAlloc);
  1060.     AllocateObjectsFromPerm(oldObjectPerm);
  1061. }
  1062.  
  1063. //----------------------------------------------------------------------------------------
  1064. // TWindow::DoMenuCommand: 
  1065. //----------------------------------------------------------------------------------------
  1066. #pragma segment MASelCommand
  1067.  
  1068. void TWindow::DoMenuCommand(CommandNumber aCommandNumber)// override 
  1069. {
  1070.     switch (aCommandNumber)
  1071.     {
  1072.         case cClose:
  1073.             CloseByUser(aCommandNumber);
  1074.             break;
  1075.  
  1076.         default:
  1077.             Inherited::DoMenuCommand(aCommandNumber);
  1078.             break;
  1079.     }
  1080. }
  1081.  
  1082. //----------------------------------------------------------------------------------------
  1083. // TWindow::DoSetupMenus: 
  1084. //----------------------------------------------------------------------------------------
  1085. #pragma segment MAWindowRes
  1086.  
  1087. void TWindow::DoSetupMenus()                    // override 
  1088. {
  1089.     if (!IsInModalState())                        // Don't enable menu/app commands if modal 
  1090.     {
  1091.         Enable(cClose, fIsClosable);            // window objects take care of themselves! 
  1092.  
  1093.         Inherited::DoSetupMenus();
  1094.     }
  1095. }
  1096.  
  1097. //----------------------------------------------------------------------------------------
  1098. // TWindow::HandlesCursor: 
  1099. //----------------------------------------------------------------------------------------
  1100. #pragma segment MAWindowRes
  1101.  
  1102. Boolean TWindow::HandlesCursor()                // override 
  1103. {
  1104.     return fHandlesCursor && (IsActive() || fDoFirstClick);
  1105. }
  1106.  
  1107. //----------------------------------------------------------------------------------------
  1108. // TWindow::LetsSubViewsHandleCursor: 
  1109. //----------------------------------------------------------------------------------------
  1110. #pragma segment MAWindowRes
  1111.  
  1112. Boolean TWindow::LetsSubViewsHandleCursor()        // override 
  1113. {
  1114.     return fLetsSubViewsHandleCursor && (IsActive() || fDoFirstClick);
  1115. }
  1116.  
  1117. //----------------------------------------------------------------------------------------
  1118. // TWindow::HandlesHelp: 
  1119. //----------------------------------------------------------------------------------------
  1120. #pragma segment MAWindowRes
  1121.  
  1122. Boolean TWindow::HandlesHelp()                    // override 
  1123. {
  1124.     return fHandlesHelp && IsActive();
  1125. }
  1126.  
  1127. //----------------------------------------------------------------------------------------
  1128. // TWindow::LetsSubViewsHandleHelp: 
  1129. //----------------------------------------------------------------------------------------
  1130. #pragma segment MAWindowRes
  1131.  
  1132. Boolean TWindow::LetsSubViewsHandleHelp()        // override 
  1133. {
  1134.     return fLetsSubViewsHandleHelp && IsActive();
  1135. }
  1136.  
  1137. //----------------------------------------------------------------------------------------
  1138. // TWindow::DrawResizeIcon: 
  1139. //----------------------------------------------------------------------------------------
  1140. #pragma segment MAWindowRes
  1141.  
  1142. void TWindow::DrawResizeIcon()
  1143. {
  1144.     if (fIsResizable && Focus())
  1145.     {
  1146.         CRect r(GetQDExtent());
  1147.         r[topLeft] = r[botRight] - CPoint(kSBarSizeMinus1, kSBarSizeMinus1);
  1148.  
  1149.         // clip down and avoid drawing the lines that delimit scroll bars
  1150.  
  1151.         CTemporaryRegion tempRgn;
  1152.         CTemporaryRegion tempRgn2;
  1153.  
  1154.         // Avoid drawing the GrowIcon if it would have been clipped
  1155.         GetClip(tempRgn);
  1156.         RectRgn(tempRgn2, &r);
  1157.         SectRgn(tempRgn2, tempRgn, tempRgn2);
  1158.         if (!EmptyRgn(tempRgn2))
  1159.         {
  1160.             SetClip(tempRgn2);
  1161.             PenNormal();
  1162.             DrawGrowIcon(fWMgrWindow);
  1163.             SetClip(tempRgn);
  1164.         }
  1165.     }
  1166. }
  1167.  
  1168. //----------------------------------------------------------------------------------------
  1169. // TWindow::Focus: 
  1170. //----------------------------------------------------------------------------------------
  1171. #pragma segment MAWindowRes
  1172.  
  1173. Boolean TWindow::Focus()                        // override 
  1174. {
  1175.     Boolean returnVal = FALSE;
  1176.  
  1177.     if (IsFocused())                            // Already focused 
  1178.     {
  1179. #if qDebug
  1180.         GrafPtr currentPort;
  1181.  
  1182.         GetPort(¤tPort);
  1183.         if (GetGrafPort() != currentPort)
  1184.             ProgramBreak("TWindow.Focus: Port is incorrect");
  1185. #endif
  1186.         returnVal = TRUE;
  1187.     }
  1188.     else if (fWMgrWindow)                        // do my own focus 
  1189.     {
  1190.         // Set the port 
  1191.         GrafPtr currentPort;
  1192.         GrafPtr theWindowPort = GetGrafPort();
  1193.  
  1194.         GetPort(¤tPort);
  1195.         if (currentPort != theWindowPort)
  1196.             SetPort(theWindowPort);
  1197.  
  1198.         CPoint qdOrigin(GetQDOrigin());
  1199.         SetOrigin(qdOrigin.h, qdOrigin.v);
  1200.         gFocusedView = this;
  1201.  
  1202.         // Add the clipping.  Clip either to the visrgn or the update region depending on whether
  1203.         // there is an invalid area.
  1204.         RgnHandle theUpdateRgn = GetUpdateRegion(fWMgrWindow);
  1205.         if (!EmptyRgn(theUpdateRgn))
  1206.         {
  1207.             // The update region is in global coords but the clip is in local coords.
  1208.             // Offset the region to make it in local coords here and restore it there
  1209.             // to save copying it
  1210.             SuperToLocalRegion(theUpdateRgn);
  1211.             CTemporaryRegion tempRgn;
  1212.  
  1213.             if (fUpdating)                        // clip TO the update region 
  1214.                 SectRgn(GetVisRegion(theWindowPort), theUpdateRgn, tempRgn);
  1215.             else                                // clip OUT the update region 
  1216.                 DiffRgn(GetVisRegion(theWindowPort), theUpdateRgn, tempRgn);
  1217.             SetClip(tempRgn);
  1218.             LocalToSuperRegion(theUpdateRgn);
  1219.         }
  1220.         else
  1221.             SetClip(GetVisRegion(theWindowPort));
  1222.  
  1223.         returnVal = TRUE;
  1224.     }
  1225.  
  1226.     return returnVal;
  1227. }
  1228.  
  1229. //----------------------------------------------------------------------------------------
  1230. // TWindow::FocusOnSuperView: 
  1231. //----------------------------------------------------------------------------------------
  1232. #pragma segment MAWindowRes
  1233.  
  1234. Boolean TWindow::FocusOnSuperView()                // override 
  1235. {
  1236.     return FALSE;
  1237. }
  1238.  
  1239. //----------------------------------------------------------------------------------------
  1240. // TWindow::GetLocationAdjustment: 
  1241. //----------------------------------------------------------------------------------------
  1242. #pragma segment MAOpen
  1243.  
  1244. void TWindow::GetLocationAdjustment(CPoint& delta)
  1245. {
  1246.     const short kMinDragArea = 4;
  1247.     VRect theVFrame(GetFrame());
  1248.     CRect theFrame(theVFrame.ToRect());
  1249.  
  1250.     // since we don't _really_ know what the drag rgn is, we'll assume that moving the
  1251.     // topleft pt of the window on screen is sufficient to make it draggable, so calculate
  1252.     // the deltas necessary to move the topleft pt into visible screen CRect.
  1253.  
  1254.     CRect visScreenRect;
  1255.     GetMaxIntersectedDevice(visScreenRect);        // NOTE: uses tempRgn 
  1256.     visScreenRect.Inset(CPoint(kMinDragArea, kMinDragArea));
  1257.  
  1258.     if (theFrame.top < visScreenRect.top)
  1259.         delta.v = visScreenRect.top - theFrame.top + fContentRegionInset.v;
  1260.     else if (theFrame.top > visScreenRect.bottom)
  1261.         delta.v = visScreenRect.bottom - theFrame.top - fContentRegionInset.v;
  1262.  
  1263.     if (theFrame.left < visScreenRect.left)
  1264.         delta.h = visScreenRect.left - theFrame.left + fContentRegionInset.h;
  1265.     else if (theFrame.left > visScreenRect.right)
  1266.         delta.h = visScreenRect.right - theFrame.right - fContentRegionInset.h;
  1267. }
  1268.  
  1269.  
  1270. //----------------------------------------------------------------------------------------
  1271. // TWindow::ForceOnScreen: ForceOnScreen guarantees that some minimal drag area is
  1272. // accessible to the user, to be dragged to the desired location.
  1273. //----------------------------------------------------------------------------------------
  1274. #pragma segment MAOpen
  1275.  
  1276. void TWindow::ForceOnScreen()
  1277. {
  1278.     const short kMinDragArea = 4;
  1279.  
  1280.     fForcedOnScreen = TRUE;
  1281.  
  1282.     // On many systems (including Color QD && the Radius FPD), it's possible to have a
  1283.     // non-rectangular desktop. Try to be nice to people who saved windows on secondary
  1284.     // screens. GrayRgn is the true indicator of the shape of the
  1285.     // desktop--screenBits.bounds is the size of the screen with the menu bar on it.
  1286.  
  1287.     CTemporaryRegion tempRgn;
  1288.     CTemporaryRegion strucRgn;
  1289.     CTemporaryRegion contRgn;
  1290.  
  1291.     Boolean rgnsWereBuilt = BuildWindowRegions(kBuild);
  1292.  
  1293.     GetWindowStructureRgn(fWMgrWindow, strucRgn);
  1294.     GetWindowContentRgn(fWMgrWindow, contRgn);
  1295.     {
  1296.         DiffRgn(strucRgn, contRgn, tempRgn);    // strucRgn less contRgn ≈≈ drag rgn
  1297.         if (EmptyRgn(tempRgn))
  1298.             CopyRgn(strucRgn, tempRgn);            // at least get the strucRgn 
  1299.     }
  1300.     BuildWindowRegions(rgnsWereBuilt);
  1301.  
  1302.     // get the desktop rgn, inset by a minimal drag area 
  1303.     CTemporaryRegion aTempRgn;
  1304.  
  1305.     CopyRgn(GetGrayRgn(), aTempRgn);            // aTempRgn = desktop rgn 
  1306.     InsetRgn(aTempRgn, kMinDragArea, kMinDragArea);// inset aTempRgn 
  1307.     SectRgn(tempRgn, aTempRgn, aTempRgn);        // do drag rgn && desktop rgn instersect ? 
  1308.  
  1309.     CPoint delta(gZeroPt);
  1310.  
  1311.     if (EmptyRgn(aTempRgn) || !RectInDrag((*(RgnHandle)aTempRgn)->rgnBBox))
  1312.         GetLocationAdjustment(delta);            // no => adjust the window's location 
  1313.  
  1314.     Locate(fLocation.ToPoint() + delta, kDontInvalidate);
  1315. }
  1316.  
  1317. //----------------------------------------------------------------------------------------
  1318. // TWindow::GetMaxIntersectedDevice: 
  1319. //----------------------------------------------------------------------------------------
  1320. #pragma segment MAWindowNonRes
  1321.  
  1322. GDHandle TWindow::GetMaxIntersectedDevice(CRect& screenRect)
  1323. {
  1324.     if (qNeedsColorQD || HasColorQD())
  1325.     {
  1326.         long maxSectArea = 0;
  1327.         CRect moveBounds;
  1328.         GetDynamicMoveBounds(moveBounds);
  1329.  
  1330.         // set fContentRegionInset && fContentDifference, ensure contrgn and strucrgn are available
  1331.         Boolean rgnsWereBuilt = BuildWindowRegions(kBuild);
  1332.         CTemporaryRegion strucRgn;
  1333.         GetWindowStructureRgn(fWMgrWindow, strucRgn);
  1334.         CRect globalStrucRect((*strucRgn)->rgnBBox);
  1335.         BuildWindowRegions(rgnsWereBuilt);
  1336.  
  1337.         GDHandle aGDHandle = GetDeviceList();
  1338.         GDHandle maxSectGD = GetMainDevice();    // set as best choice default 
  1339.         while (aGDHandle)
  1340.         {                                        // calc which scrn intersects largest part of window
  1341.             if (TestDeviceAttribute(aGDHandle, screenDevice) && TestDeviceAttribute(aGDHandle, screenActive))
  1342.             {
  1343.                 CRect aGDScreenRect((*aGDHandle)->gdRect);
  1344.                 CRect gdSectRect(globalStrucRect & aGDScreenRect);
  1345.                 if (!(aGDScreenRect & moveBounds).Empty() && !gdSectRect.Empty())
  1346.                 {
  1347.                     long sectArea = gdSectRect.GetLength(vSel) * gdSectRect.GetLength(hSel);
  1348.                     if (sectArea > maxSectArea)    // do we have a new winner? 
  1349.                     {
  1350.                         maxSectArea = sectArea;
  1351.                         maxSectGD = aGDHandle;
  1352.                     }
  1353.                 }
  1354.             }
  1355.             aGDHandle = GetNextDevice(aGDHandle);
  1356.         }
  1357.  
  1358.         if (maxSectGD != GetMainDevice())
  1359.             screenRect = (*maxSectGD)->gdRect;
  1360.         else
  1361.         {                                        // Account for menu bar on the main screen.
  1362.             // Don't just assume that its at the top of
  1363.             // the screen!
  1364.             CTemporaryRegion tempRgn;
  1365.             CRect gdRect = (*maxSectGD)->gdRect;
  1366.  
  1367.             RectRgn(tempRgn, &gdRect);            // main screen with menubar 
  1368.             SectRgn(tempRgn, GetGrayRgn(), tempRgn);// GetGrayRgn == desktop rgn w/o menubar 
  1369.             screenRect = (*(RgnHandle)tempRgn)->rgnBBox;// => main screen w/o menubar 
  1370.         }
  1371.         return maxSectGD;
  1372.     }
  1373.     else
  1374.     {                                            // Account for menu bar on the main
  1375.         // screen. Don't just assume that its at
  1376.         // the top of the screen!
  1377.         CTemporaryRegion tempRgn;
  1378.  
  1379.         RectRgn(tempRgn, &(qd.screenBits.bounds));// main screen with menubar 
  1380.         SectRgn(tempRgn, GetGrayRgn(), tempRgn);// GetGrayRgn == desktop rgn w/o menubar 
  1381.         screenRect = (*(RgnHandle)tempRgn)->rgnBBox;// => main screen w/o menubar 
  1382.         return NULL;                            // we only have GDHandle in CQD world 
  1383.     }
  1384. }
  1385.  
  1386. //----------------------------------------------------------------------------------------
  1387. // TWindow::GetGrafPort: 
  1388. //----------------------------------------------------------------------------------------
  1389. #pragma segment MAWindowRes
  1390.  
  1391. GrafPtr TWindow::GetGrafPort()                    // override 
  1392. {
  1393.     return (gPrinting || gDrawingPictScrap) ? qd.thePort : ((GrafPtr)fWMgrWindow);
  1394. }
  1395.  
  1396. //----------------------------------------------------------------------------------------
  1397. // TWindow::GetWindowTarget: 
  1398. //----------------------------------------------------------------------------------------
  1399. #pragma segment MAWindowRes
  1400.  
  1401. TEventHandler* TWindow::GetWindowTarget()
  1402. {
  1403.     return fTarget;
  1404. }
  1405.  
  1406. //----------------------------------------------------------------------------------------
  1407. // TWindow::GetTitle: 
  1408. //----------------------------------------------------------------------------------------
  1409. #pragma segment MAWindowNonRes
  1410.  
  1411. void TWindow::GetTitle(CStr255& theTitle)
  1412. {
  1413.     theTitle.Empty();
  1414.  
  1415.     if (fWMgrWindow)
  1416.         GetWTitle(fWMgrWindow, theTitle);
  1417. }
  1418.  
  1419. //----------------------------------------------------------------------------------------
  1420. // TWindow::GetWindow: 
  1421. //----------------------------------------------------------------------------------------
  1422. #pragma segment MAWindowRes
  1423.  
  1424. TWindow* TWindow::GetWindow() const                // override 
  1425. {
  1426.     return (TWindow *)this;
  1427. }
  1428.  
  1429. //----------------------------------------------------------------------------------------
  1430. // TWindow::GoAwayByUser: 
  1431. //----------------------------------------------------------------------------------------
  1432. #pragma segment MAClose
  1433.  
  1434. void TWindow::GoAwayByUser(const VPoint& theMouse)
  1435. {
  1436.     VPoint globalVMouse(theMouse);
  1437.  
  1438.     LocalToSuper(globalVMouse);
  1439.  
  1440.     if (fIsClosable && TrackGoAway(fWMgrWindow, globalVMouse.ToPoint()))
  1441.         CloseByUser(cClose);
  1442. }
  1443.  
  1444. //----------------------------------------------------------------------------------------
  1445. // TWindow::HandleMouseDown: 
  1446. //----------------------------------------------------------------------------------------
  1447. #pragma segment MASelCommand
  1448.  
  1449. Boolean TWindow::HandleMouseDown(const VPoint& theMouse,
  1450.                                  TToolboxEvent* event,
  1451.                                  CPoint hysteresis,
  1452.                                  EMouseDownType    /* mouseDownType */)// override 
  1453. {
  1454.     Boolean wasHandled = FALSE;
  1455.     short aPartCode;
  1456.     Boolean result = FALSE;
  1457.     EMouseDownType mouseDownType = kDragOrClick;
  1458.  
  1459.     // Find out where the mouse was pressed 
  1460.     aPartCode = GetPartCode(theMouse);
  1461.  
  1462.     // Test to determine if the window should be selected. To be selected,
  1463.     //  • this window must not be the active window; and
  1464.     //  • this window must not float, or if it does, it must not be front-most.
  1465.     if ((gDispatcher->GetActiveWindow(kNoFloaters) != this) && (!fFloats || (fWMgrWindow != FrontWindow())))
  1466.     {
  1467.         mouseDownType = fDoFirstClick ? kFirstClick_dragOrClick : kFirstClick_dragOnly;
  1468.  
  1469.         if (aPartCode != inContent && (aPartCode != inDrag || !event->IsCommandKeyPressed()))
  1470.         {
  1471.             Select();
  1472.             gDispatcher->UpdateAllWindows();
  1473.         }
  1474.         /*        if (aPartCode != inDrag || !event->IsCommandKeyPressed())*/
  1475.         /*        {*/
  1476.         /*            Select();*/
  1477.         /*            gDispatcher->UpdateAllWindows();*/
  1478.         /*        }*/
  1479.     }
  1480.  
  1481.     // dispatch according to where the mouse was pressed 
  1482.     switch (aPartCode)
  1483.     {
  1484.         case inContent:
  1485.             wasHandled = Inherited::HandleMouseDown(theMouse, event, hysteresis, mouseDownType);
  1486. #if qContainer
  1487.             //need to only do this if the document does not have the focus(NULL Check)
  1488.  
  1489.             if (gContainerLib && wasHandled)    //&& (gDispatcher->fCurrentDocument == NULL)) •••••••
  1490.             {
  1491.                 Boolean standardFocusAquired = CARequestStandardFocusSet(fWMgrWindow);
  1492.                 FailOSErr(CAError());
  1493. #if qDebug
  1494.                 if (!standardFocusAquired)
  1495.                 {
  1496.                     DebugStr((StringPtr)"\pFailed to aquire the standard focus from OpenDoc.");
  1497.                 }
  1498. #endif
  1499.  
  1500.             }
  1501. #endif
  1502.  
  1503.             break;
  1504.  
  1505.         case inDrag:
  1506.             MoveByUser(theMouse);
  1507.             wasHandled = TRUE;
  1508.             break;
  1509.  
  1510.         case inGrow:
  1511.             ResizeByUser(theMouse);
  1512.             wasHandled = TRUE;
  1513.             break;
  1514.  
  1515.         case inGoAway:
  1516.             GoAwayByUser(theMouse);
  1517.             wasHandled = TRUE;
  1518.             break;
  1519.  
  1520.         case inZoomIn:
  1521.         case inZoomOut:
  1522.             ZoomByUser(theMouse, aPartCode);
  1523.             wasHandled = TRUE;
  1524.             break;
  1525.  
  1526.         case inDesk:
  1527.             wasHandled = TRUE;
  1528.             break;
  1529.  
  1530.         default:
  1531.             break;
  1532.     }
  1533.  
  1534.     return wasHandled;
  1535. }
  1536.  
  1537. //----------------------------------------------------------------------------------------
  1538. // TWindow::HasPendingUpdate: 
  1539. //----------------------------------------------------------------------------------------
  1540. #pragma segment MAWindowRes
  1541.  
  1542. Boolean TWindow::HasPendingUpdate()
  1543. {
  1544.     return !EmptyRgn(GetUpdateRegion(fWMgrWindow));
  1545. }
  1546.  
  1547. //----------------------------------------------------------------------------------------
  1548. // TWindow::GetPartCode: 
  1549. //----------------------------------------------------------------------------------------
  1550. #pragma segment MAWindowRes
  1551.  
  1552. short TWindow::GetPartCode(const VPoint& theMouse)// override 
  1553. {
  1554.     short returnVal = inDesk;
  1555.  
  1556.     VPoint globalVWhere(theMouse);
  1557.  
  1558.     LocalToSuper(globalVWhere);
  1559.  
  1560.     // Call FindWindow to determine the partcode 
  1561.     WindowRef aWMgrWindow;
  1562.     short partCode = FindWindow(globalVWhere.ToPoint(), &aWMgrWindow);
  1563.     if (aWMgrWindow == fWMgrWindow)                // if we fail this sanity check, then 
  1564.         returnVal = partCode;                        // passed the sanity check so return the
  1565.                                                     // part code we got back from FindWindow
  1566. #if qDebug
  1567.     else
  1568.         ProgramBreak("in TWindow.GetPartCode: passed a VPoint that didn't belong to the window");
  1569. #endif
  1570.  
  1571.     return returnVal;
  1572. }
  1573.  
  1574. //----------------------------------------------------------------------------------------
  1575. // TWindow::BeInDocument: 
  1576. //----------------------------------------------------------------------------------------
  1577. #pragma segment MAOpen
  1578.  
  1579. void TWindow::BeInDocument(TDocument* itsDocument)
  1580. {
  1581.     CStr255 aString;
  1582.  
  1583.     Inherited::BeInDocument(itsDocument);
  1584.  
  1585.     if (fDocument && (itsDocument != fDocument))
  1586.         fDocument->DeleteWindow(this);
  1587.  
  1588.     if (itsDocument)
  1589.     {
  1590.         gDispatcher->DeleteWindow(this);        // Just in case… 
  1591.         itsDocument->AddWindow(this);
  1592.         itsDocument->GetTitle(aString);
  1593.         if (!aString.IsEmpty())                    // not an untitled document 
  1594.             SetTitleForDoc(aString);
  1595.         fNextHandler = itsDocument;
  1596.     }
  1597.     else
  1598.     {
  1599.         gDispatcher->AddWindow(this);
  1600.         fNextHandler = gDispatcher;
  1601.     }
  1602. }
  1603.  
  1604. //----------------------------------------------------------------------------------------
  1605. // TWindow::IsDismissed: 
  1606. //----------------------------------------------------------------------------------------
  1607. #pragma segment MAWindowNonRes
  1608.  
  1609. Boolean TWindow::IsDismissed()
  1610. {
  1611.     TDialogBehavior * theDialogBehavior = GetDialogBehavior();
  1612.  
  1613.     return theDialogBehavior ? theDialogBehavior->fDismissed : TRUE;
  1614. }
  1615.  
  1616. //----------------------------------------------------------------------------------------
  1617. // TWindow::Dismiss: 
  1618. //----------------------------------------------------------------------------------------
  1619. #pragma segment MAWindowNonRes
  1620.  
  1621. void TWindow::Dismiss(IDType dismisser,
  1622.                       Boolean validate)
  1623. {
  1624.     TDialogBehavior * theDialogBehavior = GetDialogBehavior();
  1625.  
  1626.     if (theDialogBehavior)
  1627.         theDialogBehavior->Dismiss(dismisser, validate);
  1628. }
  1629.  
  1630. //----------------------------------------------------------------------------------------
  1631. // TWindow::RectInDrag: 
  1632. //----------------------------------------------------------------------------------------
  1633. #pragma segment MAWindowNonRes
  1634.  
  1635. Boolean TWindow::RectInDrag(const CRect& whichRect)
  1636. // Returns true if any of the corner points of whichRect are draggable. 
  1637. {
  1638.     Boolean result = FALSE;                        // assume window isn't draggable
  1639.  
  1640.     WDefProcTypeHandle wDefProc = (WDefProcTypeHandle)GetAndLoadWDefProc(((WindowPeek)fWMgrWindow)->windowDefProc);
  1641.     if (wDefProc != NULL)
  1642.     {
  1643.         SignedByte saveState = LockHandle((Handle)wDefProc);
  1644.         WindowDefProcPtr wdef = *wDefProc;
  1645.  
  1646.         Boolean rgnsWereBuilt = BuildWindowRegions(kBuild);// regions needed for hit testing 
  1647.         short variant = GetWindowVariant(fWMgrWindow);
  1648.  
  1649.         // (ZOR) The following hack is to get around a bug in Zortech. They aren't
  1650.         // correctly applying the conversion operator 'CPoint::operator long()'.
  1651.  
  1652.         CPoint leftTop(whichRect.left, whichRect.top);
  1653.         CPoint rightBottom(whichRect.right, whichRect.bottom);
  1654.         CPoint leftBottom(whichRect.left, whichRect.bottom);
  1655.         CPoint rightTop(whichRect.right, whichRect.top);
  1656.  
  1657.         result = ((CallWindowDefProc(wdef, variant, fWMgrWindow, wHit, *((long*) & leftTop)) == wInDrag)
  1658.         || (CallWindowDefProc(wdef, variant, fWMgrWindow, wHit, *((long*) & rightBottom)) == wInDrag)
  1659.         || (CallWindowDefProc(wdef, variant, fWMgrWindow, wHit, *((long*) & leftBottom)) == wInDrag)
  1660.         || (CallWindowDefProc(wdef, variant, fWMgrWindow, wHit, *((long*) & rightTop)) == wInDrag));
  1661.  
  1662.         HSetState((Handle)wDefProc, saveState);    // restore state of wdefproc
  1663.         BuildWindowRegions(rgnsWereBuilt);        // restore state of window rgns
  1664.     }
  1665. #if qDebugMsg
  1666.     else
  1667.         ProgramBreak("###TWindow.RectInDrag: can't load wdef");
  1668. #endif
  1669.  
  1670.     return result;
  1671. }
  1672.  
  1673. //----------------------------------------------------------------------------------------
  1674. // TWindow::IsHiddenOnSuspend: 
  1675. //----------------------------------------------------------------------------------------
  1676. #pragma segment MAWindowNonRes
  1677.  
  1678. Boolean TWindow::IsHiddenOnSuspend()
  1679. {
  1680.     return fHideOnSuspend;                        // clipboard windows && floaters should
  1681.                                                 // return true (and any other window that
  1682.                                                 // wants to get hidden when the
  1683.                                                 // application is suspended by the Process
  1684.                                                 // Manager).
  1685. }
  1686.  
  1687. //----------------------------------------------------------------------------------------
  1688. // TWindow::IsShown: 
  1689. //----------------------------------------------------------------------------------------
  1690. #pragma segment MAWindowRes
  1691.  
  1692. Boolean TWindow::IsShown()                        // override 
  1693. {
  1694.     return fWMgrWindow ? IsWindowVisible(fWMgrWindow) : FALSE;
  1695. }
  1696.  
  1697. //----------------------------------------------------------------------------------------
  1698. // TWindow::IsActive: 
  1699. //----------------------------------------------------------------------------------------
  1700. #pragma segment MAWindowRes
  1701.  
  1702. Boolean TWindow::IsActive()                        // override 
  1703. {
  1704.     return fIsActive;
  1705. }
  1706.  
  1707. //----------------------------------------------------------------------------------------
  1708. // TWindow::DoInvalidateRegion: 
  1709. //----------------------------------------------------------------------------------------
  1710. #pragma segment MAWindowRes
  1711.  
  1712. void TWindow::DoInvalidateRegion(const RgnHandle badRgn)
  1713. {
  1714.     if ((qd.thePort == (GrafPtr)GetWindowPort(fWMgrWindow)) && IsShown() && !EmptyRgn(badRgn))
  1715.     {
  1716.         ::InvalRgn(badRgn);
  1717.         if (gShowInvalidations)
  1718.             FillRgn(badRgn, &qd.ltGray);
  1719.  
  1720.         // Maintain the Focus
  1721.         if (fUpdating)                        // clip should INCLUDE the update region
  1722.             UnionRgn(GetClipRegion(qd.thePort), badRgn, qd.thePort->clipRgn);
  1723.         else                                // clip should EXCLUDE the update region
  1724.             DiffRgn(GetClipRegion(qd.thePort), badRgn, qd.thePort->clipRgn);
  1725.     }
  1726. }
  1727.  
  1728. //----------------------------------------------------------------------------------------
  1729. // TWindow::DoValidateRegion: 
  1730. //----------------------------------------------------------------------------------------
  1731. #pragma segment MAWindowRes
  1732.  
  1733. void TWindow::DoValidateRegion(const RgnHandle goodRgn)
  1734. {
  1735.     if ((qd.thePort == (GrafPtr)GetWindowPort(fWMgrWindow)) && IsShown())
  1736.         if (!EmptyRgn(goodRgn))
  1737.         {
  1738.             ValidRgn(goodRgn);
  1739.  
  1740.             // Maintain the Focus
  1741.             if (fUpdating)                        // clip should INCLUDE the update region and exclude valid bits
  1742.                 DiffRgn(GetClipRegion(qd.thePort), goodRgn, qd.thePort->clipRgn);
  1743.             else                                // clip should EXCLUDE the update region and include valid bits
  1744.                 UnionRgn(GetClipRegion(qd.thePort), goodRgn, qd.thePort->clipRgn);
  1745.         }
  1746. }
  1747.  
  1748. //----------------------------------------------------------------------------------------
  1749. // TWindow::BuildWindowRegions: Calculate window size including structure region (i.e.
  1750. // title bar). To do this we need to force the window to compute its structure region by
  1751. // calling its defproc, if the window isn't shown. If build is false, set the regions back
  1752. // to empty regions, so as not to confuse the window manager. Return the previous state of
  1753. // the regions.
  1754. //----------------------------------------------------------------------------------------
  1755. #pragma segment MAWindowNonRes
  1756.  
  1757. Boolean TWindow::BuildWindowRegions(Boolean build)
  1758. {
  1759.     Boolean returnVal = kBuild;
  1760.  
  1761.     WindowRecord & theWindowRecord = *((WindowPeek)fWMgrWindow);
  1762.  
  1763.     // The regions are considered to be built if either:
  1764.     //  a) the window is shown; or
  1765.     //  b) the structure rgn is not empty.
  1766.  
  1767.     if (IsShown() || !EmptyRgn(theWindowRecord.strucRgn))
  1768.     {
  1769.         if ((build != kBuild) && !IsShown())
  1770.         {
  1771.             SetEmptyRgn(theWindowRecord.strucRgn);
  1772.             SetEmptyRgn(theWindowRecord.contRgn);
  1773.         }
  1774.     }
  1775.     else
  1776.     {
  1777.         if (build == kBuild)
  1778.         {
  1779.             WDefProcTypeHandle wDefProc = (WDefProcTypeHandle)GetAndLoadWDefProc(theWindowRecord.windowDefProc);
  1780.             if (wDefProc != NULL)
  1781.             {
  1782.                 SignedByte saveState = LockHandle((Handle)wDefProc);
  1783.                 WindowDefProcPtr wdef = *wDefProc;
  1784.                 CallWindowDefProc(wdef, GetWindowVariant(fWMgrWindow), fWMgrWindow, wCalcRgns, (long)0);
  1785.  
  1786.                 HSetState((Handle)wDefProc, saveState);
  1787.  
  1788.                 // Calculate offset from top-left of window structure to top-left of window content
  1789.                 fContentRegionInset = ((CRect &)(*theWindowRecord.contRgn)->rgnBBox)[topLeft] - ((CRect &)(*theWindowRecord.strucRgn)->rgnBBox)[topLeft];
  1790.  
  1791.                 CRect globalStrucRect = (*theWindowRecord.strucRgn)->rgnBBox;
  1792.                 CRect globalContRect = (*theWindowRecord.contRgn)->rgnBBox;
  1793.                 fContentDifference = globalStrucRect.GetSize() - globalContRect.GetSize();
  1794.             }
  1795.         }
  1796.         returnVal = !kBuild;
  1797.     }
  1798.  
  1799.     return returnVal;
  1800. }
  1801.  
  1802. //----------------------------------------------------------------------------------------
  1803. // TWindow::Select: 
  1804. //----------------------------------------------------------------------------------------
  1805. #pragma segment MAWindowRes
  1806.  
  1807. void TWindow::Select()
  1808. {
  1809.     MASelectToolboxWindow(fWMgrWindow);            // 3.5
  1810. }
  1811.  
  1812. //----------------------------------------------------------------------------------------
  1813. // TWindow::MoveByUser: 
  1814. //----------------------------------------------------------------------------------------
  1815. #pragma segment MAWindowRes
  1816.  
  1817. void TWindow::MoveByUser(const VPoint& theMouse)
  1818. {
  1819.     VPoint globalVMouse(theMouse);
  1820.  
  1821.     LocalToSuper(globalVMouse);
  1822.  
  1823.     VRect oldFrame(GetFrame());
  1824.  
  1825.     CRect moveBounds;
  1826.     GetDynamicMoveBounds(moveBounds);
  1827.     MADragWindow(fWMgrWindow, globalVMouse.ToPoint(), moveBounds);
  1828.  
  1829.     // Don't forget to tell the window object 
  1830.     if (Focus())
  1831.     {
  1832.         CPoint currLoc(((CRect &)GetWindowPort(fWMgrWindow)->portRect)[topLeft]);
  1833.         LocalToGlobal(&currLoc);                // can't use localtosuper since fLocation not updated yet
  1834.         Locate(currLoc, kDontInvalidate);
  1835.     }
  1836.  
  1837.     VRect newFrame(GetFrame());
  1838.     if (TOSADispatcher::fgDispatcher->GetDefaultTarget()->IsRecordingOn() && (newFrame != oldFrame))
  1839.     {
  1840.         TSetPropertyEvent * theEvent = new TSetPropertyEvent;
  1841.         theEvent->ISetPropertyEvent(gServerAddress, kAENoReply + kAEDontExecute, this, pBounds);
  1842.         theEvent->WriteRect(keyAEData, newFrame.ToRect());
  1843.         TAppleEvent * theReply = theEvent->Send();
  1844.         FreeIfObject(theEvent);
  1845.         FreeIfObject(theReply);
  1846.     }
  1847. }
  1848.  
  1849. //----------------------------------------------------------------------------------------
  1850. // TWindow::Open: 
  1851. //----------------------------------------------------------------------------------------
  1852. #pragma segment MAOpen
  1853.  
  1854. void TWindow::Open()                            // override 
  1855. {
  1856.     if (!IsShown())
  1857.     {
  1858.         // Keep us matching the window since we are parallel structures
  1859.         // Be sure all views are sized right
  1860.         Resize(((CRect &)GetWindowPort(fWMgrWindow)->portRect).GetSize(), kDontInvalidate);
  1861.  
  1862.         if (fMustAdapt && !fAdapted)
  1863.             AdaptToScreen();
  1864.         if ((fMustHorzCenter && !fHorzCentered) || (fMustVertCenter && !fVertCentered))
  1865.             Center(fMustHorzCenter, fMustVertCenter, IsModal());
  1866.  
  1867.         if (fMustStagger && !fStaggered)
  1868.         {
  1869.             // If both staggering and forcing on screen are specified then we must ensure
  1870.             // that the window is forced on screen FIRST so that the staggering will occur
  1871.             // in a visible (and usable) location. BUT, after staggering we must STILL
  1872.             // ensure that the window is forced on screen so, we reset the forced flag so
  1873.             // that forcing will occur on schedule later.
  1874.             if (fMustForceOnScreen && !fForcedOnScreen)
  1875.             {
  1876.                 ForceOnScreen();
  1877.                 fForcedOnScreen = FALSE;        // Make sure we can be forced again 
  1878.             }
  1879.             SimpleStagger(CPoint(kStdStaggerAmount, kStdStaggerAmount), gStandardWindowStaggerCount);
  1880.         }
  1881.         if (fMustForceOnScreen && !fForcedOnScreen)
  1882.             ForceOnScreen();
  1883.  
  1884.         // If fVisibleExtent is empty, InvalidateCoordinates so our contents will be drawn (b/c of caching)
  1885.         if (GetVisibleExtent().Empty())
  1886.             InvalidateCoordinates();
  1887.  
  1888.         if (fTarget)
  1889.             fTarget->SetTargetSelection(kDontRedraw);
  1890.         Show(TRUE, kRedraw);                    // Make me visible 
  1891.  
  1892.     }
  1893.     Inherited::Open();                            // Tell subviews to open in case they care 
  1894. }
  1895.  
  1896. //----------------------------------------------------------------------------------------
  1897. // TWindow::PoseModally: 
  1898. //----------------------------------------------------------------------------------------
  1899. #pragma segment MAWindowNonRes
  1900.  
  1901. IDType TWindow::PoseModally()
  1902. {
  1903.     TDialogBehavior * itsDialogBehavior = GetDialogBehavior();
  1904.     IDType result = kNoIdentifier;
  1905.  
  1906.     if (itsDialogBehavior)
  1907.     {
  1908.         Boolean wasModal = itsDialogBehavior->fModal;
  1909.  
  1910.         if (!wasModal)
  1911.             SetModality(TRUE);
  1912.  
  1913.         FailInfo fi;
  1914.         Try(fi)
  1915.         {
  1916.             Open();
  1917.             Select();                            // Bring it to the front 
  1918.  
  1919.             itsDialogBehavior->PoseModally();
  1920.             result = itsDialogBehavior->fDismisser;
  1921.             fi.Success();
  1922.         }
  1923.         else                                    // Recover
  1924.         {
  1925.             CloseAndFree();
  1926.             fi.ReSignal();
  1927.         }
  1928.         if (!wasModal)
  1929.             SetModality(wasModal);
  1930.     }
  1931.     else
  1932.     {
  1933.         CloseAndFree();
  1934. #if qDebug
  1935.         ProgramBreak("Can't PoseModally because the window doesn't contain a TDialogBehavior.");
  1936. #endif
  1937.  
  1938.         gErrorParm3 = "TDialogBehavior";        // show name of class 
  1939.         Failure(errMissingClass, 0);
  1940.     }
  1941.  
  1942.     return result;
  1943. }
  1944.  
  1945. //----------------------------------------------------------------------------------------
  1946. // TWindow::IsModal: 
  1947. //----------------------------------------------------------------------------------------
  1948. #pragma segment MAWindowRes
  1949.  
  1950. Boolean TWindow::IsModal()
  1951. {
  1952.     TDialogBehavior * theDialogBehavior = GetDialogBehavior();
  1953.  
  1954.     return theDialogBehavior ? theDialogBehavior->fModal : FALSE;
  1955. }
  1956.  
  1957. //----------------------------------------------------------------------------------------
  1958. // TWindow::IsInModalState: 
  1959. //----------------------------------------------------------------------------------------
  1960. #pragma segment MAWindowNonRes
  1961.  
  1962. Boolean TWindow::IsInModalState()
  1963. {
  1964.     TDialogBehavior * theDialogBehavior = GetDialogBehavior();
  1965.  
  1966.     return theDialogBehavior ? (theDialogBehavior->fModal) && (!theDialogBehavior->fDismissed) : FALSE;
  1967. }
  1968.  
  1969. //----------------------------------------------------------------------------------------
  1970. // TWindow::RemovedASubView: 
  1971. //----------------------------------------------------------------------------------------
  1972. #pragma segment MAWindowNonRes
  1973.  
  1974. void TWindow::RemovedASubView(TView* theSubView)// override 
  1975. {
  1976.     // if theSubView (or any subView) is the target, we need to 
  1977.     // set the target to this window. It might be fatal for the target to
  1978.     // point to a view no longer in the window.
  1979.  
  1980.     TEventHandler * handler;
  1981.     for (handler = gDispatcher->GetTarget(); handler != NULL; handler = handler->fNextHandler)
  1982.     {
  1983.         if (theSubView == handler)
  1984.         {
  1985.             gDispatcher->fTarget = this;
  1986.             break;
  1987.         }
  1988.     }
  1989.     for (handler = fTarget; handler != NULL; handler = handler->fNextHandler)
  1990.     {
  1991.         if (theSubView == handler)
  1992.         {
  1993.             fTarget = this;
  1994.             break;
  1995.         }
  1996.     }
  1997. }
  1998.  
  1999. //----------------------------------------------------------------------------------------
  2000. // TWindow::SetFrame: 
  2001. //----------------------------------------------------------------------------------------
  2002. #pragma segment MAWindowNonRes
  2003.  
  2004. void TWindow::SetFrame(const VRect& newFrame,
  2005.                        Boolean invalidate)        // override 
  2006. {
  2007.     if (fWMgrWindow)
  2008.     {
  2009.         if (!(newFrame.GetSize() < fSize))
  2010.         {
  2011.             if (newFrame[topLeft] != fLocation)
  2012.                 MoveWindow(fWMgrWindow, (short)newFrame[topLeft].h, (short)newFrame[topLeft].v, FALSE);//!!! VCoordinate->short
  2013.  
  2014.             if (newFrame.GetSize() != fSize)
  2015.                 SizeWindow(fWMgrWindow, (short)newFrame.GetSize().h, (short)newFrame.GetSize().v, invalidate);//!!! VCoordinate-> short
  2016.         }
  2017.         else
  2018.         {
  2019.             if (newFrame.GetSize() != fSize)
  2020.                 SizeWindow(fWMgrWindow, (short)newFrame.GetSize().h, (short)newFrame.GetSize().v, invalidate);//!!! VCoordinate-> short
  2021.  
  2022.             if (newFrame[topLeft] != fLocation)
  2023.                 MoveWindow(fWMgrWindow, (short)newFrame[topLeft].h, (short)newFrame[topLeft].v, FALSE);//!!! VCoordinate->short    
  2024.         }
  2025.     }
  2026.  
  2027.     VPoint oldSize = fSize;
  2028.     VRect vr(-kSBarSizeMinus1, -kSBarSizeMinus1, 0, 0);// standard size of grow box 
  2029.  
  2030.     if (fIsResizable && invalidate && newFrame.GetSize() != oldSize)
  2031.         InvalidateVRect(vr + fSize);            // old location
  2032.  
  2033.     Inherited::SetFrame(newFrame, invalidate);
  2034.  
  2035.     if (fIsResizable && invalidate && fSize != oldSize)
  2036.         InvalidateVRect(vr + fSize);            // new location
  2037. }
  2038.  
  2039. //----------------------------------------------------------------------------------------
  2040. // TWindow::ResizeByUser: 
  2041. //----------------------------------------------------------------------------------------
  2042. #pragma segment MAWindowNonRes
  2043.  
  2044. void TWindow::ResizeByUser(const VPoint& theMouse)
  2045. {
  2046.     if (fIsResizable)
  2047.     {
  2048.         VPoint globalVMouse(theMouse);
  2049.  
  2050.         LocalToSuper(globalVMouse);
  2051.  
  2052.         CRect resizeLimits;
  2053.         GetDynamicResizeLimits(resizeLimits);
  2054.  
  2055.         long growResult = GrowWindow(fWMgrWindow, globalVMouse.ToPoint(), &resizeLimits);
  2056.         if (growResult)
  2057.             Resize(VPoint(LoWord(growResult), HiWord(growResult)), kInvalidate);
  2058.  
  2059.         if (growResult && TOSADispatcher::fgDispatcher->GetDefaultTarget()->IsRecordingOn())
  2060.         {
  2061.             TSetPropertyEvent * theEvent = new TSetPropertyEvent;
  2062.             theEvent->ISetPropertyEvent(gServerAddress, kAENoReply + kAEDontExecute, this, pBounds);
  2063.             theEvent->WriteRect(keyAEData, GetFrame().ToRect());
  2064.             TAppleEvent * theReply = theEvent->Send();
  2065.             FreeIfObject(theEvent);
  2066.             FreeIfObject(theReply);
  2067.         }
  2068.     }
  2069. }
  2070.  
  2071. //----------------------------------------------------------------------------------------
  2072. // TWindow::SetResizeLimits: 
  2073. //----------------------------------------------------------------------------------------
  2074. #pragma segment MAOpen
  2075.  
  2076. void TWindow::SetResizeLimits(CPoint itsMinSize,
  2077.                               CPoint itsMaxSize)
  2078. {
  2079.     fResizeLimits = CRect(itsMinSize, itsMaxSize);
  2080.  
  2081.     CRect resizeLimits;
  2082.     GetDynamicResizeLimits(resizeLimits);        // get the dynamic values
  2083.  
  2084.     // If the window is zoomable, keep the window's state data current 
  2085.     if (GetWindowZoomFlag(fWMgrWindow))
  2086.     {
  2087.         CRect theStdState;
  2088.         GetWindowStandardState(fWMgrWindow, &theStdState);
  2089.         theStdState.right = (short)Min(theStdState.right, fLocation.h + resizeLimits.right - 1);//!!! long-> short
  2090.         theStdState.bottom = (short)Min(theStdState.bottom, fLocation.v + resizeLimits.bottom - 1);//!!! long-> short
  2091.         SetWindowStandardState(fWMgrWindow, &theStdState);
  2092.     }
  2093.  
  2094.     // If the window is not sized within the new limits, resize it to fit
  2095.     VPoint newSize(fSize);
  2096.     newSize.ConstrainTo(resizeLimits);
  2097.  
  2098.     Resize(newSize, IsVisible());
  2099.  
  2100. }
  2101.  
  2102. //----------------------------------------------------------------------------------------
  2103. // TWindow::DoEvent: 
  2104. //----------------------------------------------------------------------------------------
  2105. #pragma segment MAWindowRes
  2106.  
  2107. void TWindow::DoEvent(EventNumber eventNumber,
  2108.                       TEventHandler* source,
  2109.                       TEvent* event)            // Override
  2110.  
  2111. {
  2112.     switch (eventNumber)
  2113.     {
  2114.         case mBecameTarget:
  2115.             if (IsActive())
  2116.                 SetWindowTarget(source);
  2117.             break;
  2118.  
  2119.         default:
  2120.             Inherited::DoEvent(eventNumber, source, event);
  2121.             break;
  2122.     }
  2123. }
  2124.  
  2125. //----------------------------------------------------------------------------------------
  2126. // TWindow::SetWindowTarget: 
  2127. //----------------------------------------------------------------------------------------
  2128. #pragma segment MAWindowRes
  2129.  
  2130. void TWindow::SetWindowTarget(TEventHandler* newTarget)
  2131. {
  2132.     if (!newTarget)                                // Would be annoying if a NULL got in here! 
  2133.         newTarget = this;
  2134.     if (newTarget != fTarget)
  2135.     {
  2136.         fTarget->ResignedWindowTarget();
  2137.         fTarget = newTarget;
  2138.         newTarget->BecameWindowTarget();
  2139.     }
  2140. }
  2141.  
  2142. //----------------------------------------------------------------------------------------
  2143. // TWindow::SetTitle: 
  2144. //----------------------------------------------------------------------------------------
  2145. #pragma segment MAWindowNonRes
  2146.  
  2147. void TWindow::SetTitle(const CStr255& newTitle)
  2148. {
  2149.     CStr255 oldTitle;
  2150.  
  2151.     GetWTitle(fWMgrWindow, oldTitle);            // to minimize flash, we only set the
  2152.                                                 // title if it's different from the
  2153.                                                 // current title
  2154.     if (oldTitle != newTitle)
  2155.         ::SetWTitle(fWMgrWindow, newTitle);
  2156. }
  2157.  
  2158. //----------------------------------------------------------------------------------------
  2159. // TWindow::SetTitleForDoc: 
  2160. //----------------------------------------------------------------------------------------
  2161. #pragma segment MAFile
  2162.  
  2163. void TWindow::SetTitleForDoc(const CStr255& newDocTitle)
  2164. {
  2165.     if (fPreDocname > 0)                        // optimize for case of nothing to do 
  2166.     {
  2167.         CStr255 title;
  2168.         GetTitle(title);
  2169.  
  2170.         if (SubstituteInTitle(title, newDocTitle, fPreDocname, fConstTitle))
  2171.             SetTitle(title);
  2172.     }
  2173. }
  2174.  
  2175. //----------------------------------------------------------------------------------------
  2176. // TWindow::AboutToLoseControl: 
  2177. //----------------------------------------------------------------------------------------
  2178. #pragma segment MAWindowNonRes
  2179.  
  2180. void TWindow::AboutToLoseControl()
  2181. {
  2182.     if (IsShown() && IsHiddenOnSuspend())
  2183.     {
  2184.         fWasHiddenOnSuspend = TRUE;
  2185.         Boolean oldManageActivation = fGenerateActivates;
  2186.         fGenerateActivates = FALSE;
  2187.         Show(FALSE, kRedraw);
  2188.         fGenerateActivates = oldManageActivation;
  2189.     }
  2190. }
  2191.  
  2192. //----------------------------------------------------------------------------------------
  2193. // TWindow::RegainControl: 
  2194. //----------------------------------------------------------------------------------------
  2195. #pragma segment MAWindowNonRes
  2196.  
  2197. void TWindow::RegainControl()
  2198. {
  2199.     if (fWasHiddenOnSuspend)
  2200.     {
  2201.         fWasHiddenOnSuspend = FALSE;
  2202.         // Any necessary activation is handled in TApplication.HandleSystemEvent 
  2203.         Boolean oldManageActivation = fGenerateActivates;
  2204.         fGenerateActivates = FALSE;
  2205.         Show(TRUE, kRedraw);
  2206.         fGenerateActivates = oldManageActivation;
  2207.     }
  2208. }
  2209.  
  2210. //----------------------------------------------------------------------------------------
  2211. // TWindow::Show: 
  2212. //----------------------------------------------------------------------------------------
  2213. #pragma segment MAWindowNonRes
  2214.  
  2215. void TWindow::Show(Boolean state,
  2216.                    Boolean redraw)                // override 
  2217. {
  2218.     if (state)
  2219.     {
  2220.         // Be sure all views are sized right 
  2221.         Resize(((CRect &)GetWindowPort(fWMgrWindow)->portRect).GetSize(), redraw);
  2222.     }
  2223.  
  2224.     if (fGenerateActivates && !fFloats)
  2225.     {
  2226.         if (state)
  2227.             MAShowWindow(fWMgrWindow);
  2228.         else
  2229.             MAHideWindow(fWMgrWindow);
  2230.     }
  2231.     else
  2232.     {
  2233.         if (fFloats)
  2234.             HiliteWindow(fWMgrWindow, state);
  2235.  
  2236.         ShowHide(fWMgrWindow, state);
  2237.         if (!state)
  2238.             Activate(FALSE);                    // at least de-activate ourselves when
  2239.         // hiding
  2240.     }
  2241.  
  2242.     // manage floaters window list position
  2243.     if (state && fFloats)
  2244.     {
  2245.         // if we are behind any of the normal document windows, we move
  2246.         // back into the floating layer
  2247.         CWMgrIterator iter;
  2248.         Boolean foundNormalDocWindow = FALSE;
  2249.         Boolean foundOurself = FALSE;
  2250.         Boolean needToMove = FALSE;
  2251.         for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  2252.         {
  2253.             if (aWindowPtr == fWMgrWindow)
  2254.             {
  2255.                 foundOurself = TRUE;
  2256.                 needToMove = foundNormalDocWindow;
  2257.             }
  2258.             else if (!IsModalWindow(aWindowPtr) && !IsFloatWindow(aWindowPtr))
  2259.                 foundNormalDocWindow = TRUE;
  2260.         }
  2261.  
  2262.         if (needToMove)
  2263.             BringToFront(fWMgrWindow);
  2264.     }
  2265.  
  2266.     // manage activation:
  2267.     if (fFloats)
  2268.         Activate(state);                        // for floaters, activation == visibility 
  2269.     else if ((!state) && IsActive())
  2270.         Activate(FALSE);                        // if active, de-activate ourselves when hiding
  2271.  
  2272.     Inherited::Show(state, redraw);
  2273. }
  2274.  
  2275. //----------------------------------------------------------------------------------------
  2276. // TWindow::SimpleStagger: 
  2277. //----------------------------------------------------------------------------------------
  2278. #pragma segment MAOpen
  2279.  
  2280. void TWindow::SimpleStagger(CPoint delta,
  2281.                             short& counter)
  2282. {
  2283.     fStaggered = TRUE;
  2284.     VRect theFrame(GetFrame());
  2285.  
  2286.     CRect moveBounds;
  2287.     GetDynamicMoveBounds(moveBounds);
  2288.  
  2289.     theFrame[botRight] = (theFrame[topLeft] + VPoint(moveBounds[botRight])) - theFrame[botRight];
  2290.  
  2291.     // This covers the case of delta.h && delta.v both >= 0; if either is less than 0, the
  2292.     // right (bottom) limit is set to the left (top) edge of the screen -- allowing for
  2293.     // some margin. This makes the right (bottom) edge less than the left (top) edge, but
  2294.     // this is OK since the/ statement below will be dividing 2 negative numbers.
  2295.  
  2296.     if (delta.h < 0)
  2297.         theFrame.right = fMoveBounds.left;
  2298.     if (delta.v < 0)
  2299.         theFrame.bottom = fMoveBounds.top;
  2300.  
  2301.     // This code avoids divide by zero problems 
  2302.     short nSlots = (!delta.h || !delta.v) ? 0 : (short)Min((theFrame.GetLength(hSel) + delta.h - 1) / delta.h, (theFrame.GetLength(vSel) + delta.v - 1) / delta.v);//!!! long-> short
  2303.     short slot = nSlots ? counter % nSlots : 0;
  2304.  
  2305.     if (slot)                                    // move the window 
  2306.     {
  2307.         // The place to position the window 
  2308.         Locate(theFrame[topLeft] + VPoint((slot * delta.h), (slot * delta.v)), kDontInvalidate);
  2309.     }
  2310.  
  2311.     ++counter;
  2312. }
  2313.  
  2314. //----------------------------------------------------------------------------------------
  2315. // TWindow::BeginUpdate: 
  2316. //----------------------------------------------------------------------------------------
  2317. void TWindow::BeginUpdate()
  2318. {
  2319.     fUpdating = TRUE;                            // So TWindow.Focus will know to focus TO
  2320.     // the update rgn
  2321.  
  2322.     //
  2323.     // Set the flags that let the GetVisibleRegion and GetUpdateRegion functions
  2324.     // return the correct regions.
  2325.     //
  2326.     pInBeginUpdate = TRUE;
  2327.     pInBeginUpdateWindowPtr = fWMgrWindow;
  2328.  
  2329.     //
  2330.     // Save the update region for reference, since ::BeginUpdate smashes it
  2331.     //
  2332.     if (!pSavedUpdateRegion)
  2333.         pSavedUpdateRegion = NewRgn();
  2334.     CopyRgn(((WindowPeek)fWMgrWindow)->updateRgn, pSavedUpdateRegion);
  2335.  
  2336.     // Yes, I know that there is an LMGetSaveVisRgn call available. The problem is that the Process Manager
  2337.     // doesn't [always?] switch the low memory global that stores the saved visRgn and that makes it
  2338.     // d*mn near impossible to debug-step through any framework updating code as the region
  2339.     // referenced there keeps getting modified. Copying the region to pSavedVisRegion is somewhat
  2340.     // less efficient... but actually works correctly.
  2341.     if (!pSavedVisRegion)
  2342.         pSavedVisRegion = NewRgn();
  2343.     CopyRgn(fWMgrWindow->visRgn, pSavedVisRegion);
  2344.  
  2345.     //
  2346.     // Save the offset of the visRgn since we'll need it in the GetVisRegion accessor function
  2347.     //
  2348.     RgnHandle savedVisRgn = pSavedVisRegion;
  2349.     pSavedVisRegionOriginalOffset = CPoint(((CRect &)(*savedVisRgn)->rgnBBox)[topLeft]) - ((CRect &)fWMgrWindow->portRect)[topLeft];
  2350.  
  2351.     ::BeginUpdate(fWMgrWindow);
  2352. }
  2353.  
  2354. //----------------------------------------------------------------------------------------
  2355. // TWindow::EndUpdate: 
  2356. //----------------------------------------------------------------------------------------
  2357. void TWindow::EndUpdate()
  2358. {
  2359.     fUpdating = FALSE;
  2360.  
  2361.     pInBeginUpdate = FALSE;
  2362.     pInBeginUpdateWindowPtr = NULL;
  2363.     SetEmptyRgn(pSavedUpdateRegion);
  2364.  
  2365.     SetEmptyRgn(pSavedVisRegion);
  2366.  
  2367.     ::EndUpdate(fWMgrWindow);
  2368.  
  2369. }
  2370.  
  2371. //----------------------------------------------------------------------------------------
  2372. // TWindow::Update: 
  2373. //----------------------------------------------------------------------------------------
  2374. #pragma segment MAWindowRes
  2375.  
  2376. void TWindow::Update()                            // override 
  2377. {
  2378.     // if we are already in the process of updating, don't do anything.
  2379.     if (!fUpdating)
  2380.     {
  2381.         if (HasPendingUpdate())
  2382.         {
  2383.             FailInfo fi;
  2384.             Try(fi)
  2385.             {
  2386.                 InvalidateFocus();
  2387.                 BeginUpdate();
  2388. #if qDebug
  2389.                 if (gShowInvalidations && Focus())
  2390.                 {
  2391.                     FillRect(&GetQDExtent(), &qd.ltGray);// we'll be clipped appropriately
  2392.                     long finalTicks;
  2393.                     Delay(15, &finalTicks);        // so you can see it
  2394.                 }
  2395. #endif
  2396.  
  2397.                 VRect updateVRect;
  2398.                 RectToVRect((*GetUpdateRegion(fWMgrWindow))->rgnBBox, updateVRect);
  2399.                 SuperToLocalVRect(updateVRect);
  2400.  
  2401.                 HandleDraw(updateVRect);
  2402.  
  2403.                 fi.Success();
  2404.             }
  2405.             else                                // Recover
  2406.             {
  2407.                 // Or we get into an infinite loop 
  2408.                 // trying to update the window when 
  2409.                 // displaying an alert 
  2410.                 EndUpdate();
  2411.                 InvalidateFocus();
  2412.  
  2413.                 fi.ReSignal();
  2414.             }
  2415.  
  2416.             EndUpdate();
  2417.             InvalidateFocus();
  2418.         }
  2419.     }
  2420. }
  2421.  
  2422. //----------------------------------------------------------------------------------------
  2423. // TWindow::GetStandardStateFrame:  Former nested routine, now a private method
  2424. //----------------------------------------------------------------------------------------
  2425. #pragma segment MAWindowNonRes
  2426.  
  2427. void TWindow::GetStandardStateFrame(const VRect& boundingRect,
  2428.                                     VRect& stdFrame)
  2429. {
  2430.     const short edge = 2;                        // leave space around window structure area, settable?
  2431.     VPoint delta;
  2432.     VRect localBoundingRect = boundingRect;
  2433.  
  2434.     localBoundingRect.Inset(VPoint(edge, edge));
  2435.  
  2436.     // calculate the maximum structure size 
  2437.     CRect resizeLimits;
  2438.     GetDynamicResizeLimits(resizeLimits);
  2439.  
  2440.     delta.h = Min((localBoundingRect.GetLength(hSel)), resizeLimits[botRight][hSel] + fContentDifference[hSel]);//!!! long-> short
  2441.     delta.v = Min((localBoundingRect.GetLength(vSel)), resizeLimits[botRight][vSel] + fContentDifference[vSel]);//!!! long-> short
  2442.  
  2443.     // Relocate the view only if necessary, and then move it as little as possible
  2444.     if ((fLocation.v >= localBoundingRect.top) && ((fLocation.v + delta.v - fContentDifference.v - 1) <= localBoundingRect.bottom))
  2445.         stdFrame.top = fLocation.v;
  2446.     else if (fLocation.v < localBoundingRect.top)
  2447.         stdFrame.top = localBoundingRect.top;
  2448.     else
  2449.         stdFrame.top = localBoundingRect.bottom - delta.v + fContentRegionInset.v;
  2450.     // stdFrame.top = localBoundingRect.top + fContentRegionInset.v + ((localBoundingRect.GetLength(vSel)) - delta.v) / 2;
  2451.  
  2452.     if ((fLocation.h >= localBoundingRect.left) && ((fLocation.h + delta.h - fContentDifference.h - 1) <= localBoundingRect.right))
  2453.         stdFrame.left = fLocation.h;
  2454.     else if (fLocation.h < localBoundingRect.left)
  2455.         stdFrame.left = localBoundingRect.left;
  2456.     else
  2457.         stdFrame.left = localBoundingRect.right - delta.h + fContentRegionInset.h;
  2458.     // stdFrame.left = localBoundingRect.left + fContentRegionInset.h + ((localBoundingRect.GetLength(hSel)) - delta.h) / 2;
  2459.  
  2460.     stdFrame[botRight] = stdFrame[topLeft] + delta - VPoint(fContentDifference) - VPoint(1, 1);
  2461. }
  2462.  
  2463. //----------------------------------------------------------------------------------------
  2464. // TWindow::GetUserStateFrame: 
  2465. //----------------------------------------------------------------------------------------
  2466. #pragma segment MAWindowNonRes
  2467.  
  2468. void TWindow::GetUserStateFrame(const VRect&    /* boundingRect */ ,
  2469.                                 VRect& userFrame)
  2470. {
  2471.     if (GetWindowZoomFlag(fWMgrWindow))            // has zoom box
  2472.     {
  2473.         CRect userQDState;
  2474.         GetWindowUserState(fWMgrWindow, &userQDState);
  2475.         userFrame = userQDState;
  2476.     }
  2477. #if qDebug
  2478.     else
  2479.         ProgramBreak("Whoops");
  2480. #endif
  2481.  
  2482. }
  2483.  
  2484. //----------------------------------------------------------------------------------------
  2485. // TWindow::Zoom: 
  2486. //----------------------------------------------------------------------------------------
  2487. #pragma segment MAWindowNonRes
  2488.  
  2489. void TWindow::Zoom(short partCode)
  2490. {
  2491.     CRect aGDScreenRect;
  2492.     VRect itsNewFrame;
  2493.  
  2494.     // Find out where the window would like to be zoomed out to 
  2495.     GetMaxIntersectedDevice(aGDScreenRect);
  2496.     VRect aGDScreenVRect(aGDScreenRect);
  2497.  
  2498.     if (partCode == inZoomOut)
  2499.     {
  2500.         // new zoom-out CRect
  2501.         GetStandardStateFrame(aGDScreenVRect, itsNewFrame);
  2502.         if (GetWindowZoomFlag(fWMgrWindow))        // has zoom box
  2503.         {
  2504.             CRect newFrame = itsNewFrame.ToRect();
  2505.             SetWindowStandardState(fWMgrWindow, &newFrame);
  2506.         }
  2507.     }
  2508.     else
  2509.     {                                            // new zoom-in CRect
  2510.         GetUserStateFrame(aGDScreenVRect, itsNewFrame);
  2511.         if (GetWindowZoomFlag(fWMgrWindow))        // has zoom box
  2512.         {
  2513.             CRect newFrame = itsNewFrame.ToRect();
  2514.             GetWindowUserState(fWMgrWindow, &newFrame);
  2515.         }
  2516.     }
  2517.  
  2518.     if (Focus())                                // The ROM requires that thePort be the window being zoomed.
  2519.     {
  2520.         // if the window both moves and resizes then call the ZoomWindow trap to get the right visual
  2521.         // effect.
  2522.         // If it only moves OR resizes then just call SetFrame since more bits
  2523.         // may be preserved.
  2524.         if (itsNewFrame[topLeft] != fLocation && itsNewFrame.GetSize() != fSize)
  2525.         {
  2526.             EraseRect(&GetQDExtent());
  2527.  
  2528.             if (GetWindowZoomFlag(fWMgrWindow))    // check for a zoomable defproc 
  2529.                 ZoomWindow(fWMgrWindow, partCode, FALSE);
  2530.         }
  2531.  
  2532.         // let the View know what we've done 
  2533.         SetFrame(itsNewFrame, kInvalidate);
  2534.     }
  2535. }
  2536.  
  2537. //----------------------------------------------------------------------------------------
  2538. // TWindow::ZoomByUser: 
  2539. //----------------------------------------------------------------------------------------
  2540. #pragma segment MAWindowNonRes
  2541.  
  2542. void TWindow::ZoomByUser(const VPoint& theMouse,
  2543.                          short partCode)
  2544. {
  2545.     VPoint globalVMouse(theMouse);
  2546.  
  2547.     LocalToSuper(globalVMouse);
  2548.     if (TrackBox(fWMgrWindow, globalVMouse.ToPoint(), partCode))
  2549.     {
  2550.         Zoom(partCode);
  2551.  
  2552.         if (TOSADispatcher::fgDispatcher->GetDefaultTarget()->IsRecordingOn())
  2553.         {
  2554.             TSetPropertyEvent * theEvent = new TSetPropertyEvent;
  2555.             theEvent->ISetPropertyEvent(gServerAddress, kAENoReply + kAEDontExecute, this, pIsZoomed);
  2556.             theEvent->WriteBoolean(keyAEData, (partCode == inZoomOut));
  2557.             TAppleEvent * theReply = theEvent->Send();
  2558.             FreeIfObject(theEvent);
  2559.             FreeIfObject(theReply);
  2560.         }
  2561.     }
  2562. }
  2563.  
  2564. //----------------------------------------------------------------------------------------
  2565. // TWindow::GetDynamicMoveBounds:
  2566. //----------------------------------------------------------------------------------------
  2567. #pragma segment MAWindowRes
  2568.  
  2569. void TWindow::GetDynamicMoveBounds(CRect& moveBounds)
  2570. {
  2571.     //
  2572.     // Any value is made dynamic by leaving it at zero. Any non-zero values
  2573.     // are honored.
  2574.     //
  2575.     moveBounds = fMoveBounds;
  2576.  
  2577.     CRect grayBox((*GetGrayRgn())->rgnBBox);
  2578.     grayBox.Inset(CPoint(4, 4));
  2579.  
  2580.     if (!fMoveBounds.top)                        // dynamic
  2581.         moveBounds.top = grayBox.top;
  2582.  
  2583.     if (!fMoveBounds.left)                        // dynamic
  2584.         moveBounds.left = grayBox.left;
  2585.  
  2586.     if (!fMoveBounds.bottom)                    // dynamic
  2587.         moveBounds.bottom = grayBox.bottom;
  2588.  
  2589.     if (!fMoveBounds.right)                        // dynamic
  2590.         moveBounds.right = grayBox.right;
  2591. }
  2592.  
  2593. //----------------------------------------------------------------------------------------
  2594. // TWindow::GetDynamicResizeLimits:
  2595. //----------------------------------------------------------------------------------------
  2596. #pragma segment MAWindowRes
  2597.  
  2598. void TWindow::GetDynamicResizeLimits(CRect& resizeLimits)
  2599. {
  2600.     //
  2601.     // Any value in fResizeLimits is made dynamic by leaving it at zero. Any
  2602.     // non-zero values are honored.
  2603.     //
  2604.     resizeLimits = fResizeLimits;
  2605.  
  2606.     // maximum size vertically
  2607.     static const short kHalfTitleBar = 8;
  2608.     CPoint grayRgnBBoxSize(CRect((*GetGrayRgn())->rgnBBox).GetSize());
  2609.  
  2610.     if (!fResizeLimits.bottom)                    // dynamic
  2611.         resizeLimits.bottom = grayRgnBBoxSize.v - kHalfTitleBar;
  2612.  
  2613.     // maximum size horizontally
  2614.     if (!fResizeLimits.right)                    // dynamic
  2615.         resizeLimits.right = grayRgnBBoxSize.h;
  2616.  
  2617.     //
  2618.     // Ideally the window's settings should come from the window template and
  2619.     // the default settings should come from a resource (with a constant for a
  2620.     // backstop if the resource is not present). However, the template format
  2621.     // is not changing (for MA 3.3) and I'd have to check with the MacApp team
  2622.     // about defining a resource for the default.
  2623.     //
  2624.     // I am able to fix one persistent problem here, though. User interface
  2625.     // elements have been shrinking over the past several years and very small
  2626.     // status windows have become more common. MacApp has supplied a default
  2627.     // minimum resize limit of 80, 80 pixels in previous releases. This is too
  2628.     // large for these small windows and yet is still close to reasonable. I
  2629.     // propose to reduce the constant minimum to a slightly smaller value than
  2630.     // before (approximately two scroll arrows plus a thumb plus a resize icon)
  2631.     // as well as modifying the calculation of the default value to accept the
  2632.     // current size of the window as the minimum if it is smaller than the
  2633.     // constant values.
  2634.     //
  2635.     static const short kMinWindowWidth = kStdSzSBar * 4;
  2636.     static const short kMinWindowHeight = kStdSzSBar * 4;
  2637.  
  2638.     // minimum size vertically
  2639.     if (!fResizeLimits.top)                        // dynamic
  2640.     {
  2641.         resizeLimits.top = Min(kMinWindowHeight, resizeLimits.bottom);
  2642.         // capture the minimum if it will be smaller than the default
  2643.         if (fSize.v < resizeLimits.top)
  2644.             resizeLimits.top = fResizeLimits.top = fSize.v;
  2645.     }
  2646.  
  2647.     // minimum size horizontally
  2648.     if (!fResizeLimits.left)                    // dynamic
  2649.     {
  2650.         resizeLimits.left = Min(kMinWindowWidth, resizeLimits.right);
  2651.         // capture the minimum if it will be smaller than the default
  2652.         if (fSize.v < resizeLimits.left)
  2653.             resizeLimits.left = fResizeLimits.left = fSize.h;
  2654.     }
  2655. }
  2656.  
  2657. //----------------------------------------------------------------------------------------
  2658. // TWindow::GetSpecifierForm:
  2659. //----------------------------------------------------------------------------------------
  2660. #pragma segment MAWindowNonRes
  2661.  
  2662. DescType TWindow::GetSpecifierForm()
  2663. {
  2664.     CStr255 theName;
  2665.     GetTitle(theName);
  2666.  
  2667.     DescType theForm = (!theName.IsEmpty()) ? formName : MScriptableObject::GetSpecifierForm();
  2668.  
  2669.     return theForm;
  2670. }
  2671.  
  2672. //----------------------------------------------------------------------------------------
  2673. // TWindow::CountContainedObjects:
  2674. //----------------------------------------------------------------------------------------
  2675. #pragma segment MAWindowNonRes
  2676.  
  2677. long TWindow::CountContainedObjects(DescType desiredType)
  2678. {
  2679.     long result = 0;
  2680.  
  2681.     if (IsShown() && !fFloats)                    // don't support floaters and invisible windows 
  2682.     {
  2683.         if (gDispatcher->IsDocumentClass(desiredType))
  2684.             result = 1;
  2685.         else if (fDocument)
  2686.             result = fDocument->CountContainedObjects(desiredType);
  2687.     }
  2688.     else
  2689.  
  2690.         if (!result)
  2691.             result = MScriptableObject::CountContainedObjects(desiredType);
  2692.  
  2693.     return result;
  2694. }
  2695.  
  2696. //----------------------------------------------------------------------------------------
  2697. // TWindow::GetCommandContext
  2698. //----------------------------------------------------------------------------------------
  2699. #pragma segment MAOSLDispatch
  2700.  
  2701. TCommandHandler* TWindow::GetCommandContext(const CommandNumber/* aCommandNumber */ ) const
  2702. {
  2703.     return fDocument ? (TCommandHandler*)fDocument : gDispatcher;
  2704. }
  2705.  
  2706. //----------------------------------------------------------------------------------------
  2707. // TWindow::GetContainedObject:
  2708. //----------------------------------------------------------------------------------------
  2709. #pragma segment MAWindowNonRes
  2710.  
  2711. MScriptableObject* TWindow::GetContainedObject(DescType desiredType,
  2712.                                                DescType selectionForm,
  2713.                                                const CAEDesc& selectionData)
  2714. {
  2715.     MScriptableObject * result = NULL;
  2716.     if (IsShown() && !fFloats)
  2717.     {
  2718.         if (gDispatcher->IsDocumentClass(desiredType))
  2719.             result = fDocument;
  2720.         else if (fDocument && (desiredType != cProperty) && (desiredType != GetOMClass()))
  2721.             result = fDocument->GetContainedObject(desiredType, selectionForm, selectionData);
  2722.     }
  2723.  
  2724.     if (!result)
  2725.         result = MScriptableObject::GetContainedObject(desiredType, selectionForm, selectionData);
  2726.  
  2727.     return result;
  2728. }
  2729.  
  2730. //----------------------------------------------------------------------------------------
  2731. // TWindow::GetObjectProperty:
  2732. //----------------------------------------------------------------------------------------
  2733. #pragma segment MAWindowNonRes
  2734.  
  2735. Boolean TWindow::GetObjectProperty(CAEDesc& thePropertyValue,
  2736.                                    DescType whichProperty,
  2737.                                    const CAEDesc& desiredType)
  2738. {
  2739.     Boolean hasProperty = TRUE;
  2740.     FailInfo fi;
  2741.     Try(fi)
  2742.     {
  2743.         switch (whichProperty)
  2744.         {
  2745.             case pClass:
  2746.                 thePropertyValue.PutType(GetOMClass());
  2747.                 break;
  2748.  
  2749.             case pBounds:
  2750.                 thePropertyValue.PutRect(ViewToQDRect(GetFrame()));
  2751.                 break;
  2752.  
  2753.             case pName:
  2754.                 {
  2755.                     CStr255 theName;
  2756.                     GetTitle(theName);
  2757.                     thePropertyValue.PutString(theName);
  2758.                     break;
  2759.                 }
  2760.  
  2761.             case pHasCloseBox:
  2762.                 thePropertyValue.PutBoolean(fIsClosable);
  2763.                 break;
  2764.  
  2765.             case pHasTitleBar:
  2766.                 thePropertyValue.PutBoolean(fContentDifference != gZeroPt);
  2767.                 break;
  2768.  
  2769.             case pIndex:
  2770.                 {
  2771.                     CWMgrIterator iter;
  2772.                     long index = 0;
  2773.                     TWindow * aWindow = NULL;
  2774.                     hasProperty = FALSE;
  2775.  
  2776.                     for (WindowRef aWinPtr = iter.FirstWMgrWindow(); iter.More() && (aWindow != this); aWinPtr = iter.NextWMgrWindow())
  2777.                     {
  2778.                         aWindow = gDispatcher->WMgrToWindow(aWinPtr);
  2779.                         // count its index either as a floater or non-floater
  2780.                         if (aWindow && aWindow->IsShown() && (fFloats == aWindow->fFloats))
  2781.                         {
  2782.                             index++;
  2783.                             if (aWindow == this)
  2784.                             {
  2785.                                 thePropertyValue.PutLong(index);
  2786.                                 hasProperty = TRUE;
  2787.                             }
  2788.                         }
  2789.                     }
  2790.                     break;
  2791.                 }
  2792.  
  2793.             case pIsModal:
  2794.                 thePropertyValue.PutBoolean(IsModal());
  2795.                 break;
  2796.  
  2797.             case pIsResizable:
  2798.                 thePropertyValue.PutBoolean(fIsResizable);
  2799.                 break;
  2800.  
  2801.             case pIsZoomable:
  2802.                 thePropertyValue.PutBoolean((fProcID) & zoomDocProc);
  2803.                 break;
  2804.  
  2805.             case pIsZoomed:
  2806.                 {
  2807.                     CRect aGDScreenRect;
  2808.                     GetMaxIntersectedDevice(aGDScreenRect);
  2809.                     VRect aGDScreenVRect(aGDScreenRect);
  2810.                     VRect zoomFrame;
  2811.                     GetUserStateFrame(aGDScreenVRect, zoomFrame);
  2812.                     thePropertyValue.PutBoolean((GetFrame() != zoomFrame));
  2813.                     break;
  2814.                 }
  2815.  
  2816.             case pSelection:
  2817.                 {
  2818.                     TDocument * theDoc = fDocument;
  2819.                     if (theDoc)
  2820.                     {
  2821.                         TDesignator * theUserSelection = theDoc->GetUserSelection();
  2822.                         if (theUserSelection)
  2823.                         {
  2824.                             CTempDesc propData;
  2825.                             theUserSelection->MakeObjectSpecifier(propData, theUserSelection->GetSpecifierForm());
  2826.                             thePropertyValue = propData;
  2827.                         }
  2828.                         else
  2829.                             FailOSErr(errAENoSuchObject);
  2830.                     }
  2831.                     break;
  2832.                 }
  2833.  
  2834.             default:
  2835.                 {
  2836.                     // Users will frequently refer to the window when they mean the document. If this window
  2837.                     // has a document we'll give it a crack at supplying the property.
  2838.                     if (fDocument)
  2839.                         hasProperty = fDocument->GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  2840.                     else
  2841.                         hasProperty = MScriptableObject::GetObjectProperty(thePropertyValue, whichProperty, desiredType);
  2842.                 }
  2843.                 break;
  2844.         }
  2845.         fi.Success();
  2846.     }
  2847.     else                                        // Recover
  2848.     {
  2849.         hasProperty = FALSE;
  2850.     }
  2851.     return hasProperty;
  2852. }
  2853.  
  2854. //----------------------------------------------------------------------------------------
  2855. // TWindow::GetSetPropertyInfo:
  2856. //----------------------------------------------------------------------------------------
  2857. #pragma segment MAWindowNonRes
  2858.  
  2859. void TWindow::GetSetPropertyInfo(DescType whichProperty,
  2860.                                  CommandNumber& cmdNum,
  2861.                                  Boolean& canUndo,
  2862.                                  Boolean& causesChange,
  2863.                                  TCommandHandler*& theContext)
  2864. {
  2865.     MScriptableObject::GetSetPropertyInfo(whichProperty, cmdNum, canUndo, causesChange, theContext);
  2866.  
  2867.     if (whichProperty == pBounds || whichProperty == pIsZoomed || whichProperty == pName)
  2868.     {
  2869.         canUndo = FALSE;
  2870.         causesChange = FALSE;
  2871.     }
  2872. }
  2873.  
  2874. //----------------------------------------------------------------------------------------
  2875. // TWindow::SetObjectProperty:
  2876. //----------------------------------------------------------------------------------------
  2877. #pragma segment MAWindowNonRes
  2878.  
  2879. void TWindow::SetObjectProperty(const CAEDesc& thePropertyValue,
  2880.                                 DescType whichProperty)
  2881. {
  2882.     switch (whichProperty)
  2883.     {
  2884.         case pBounds:
  2885.             {
  2886.                 CRect theWindowRect;
  2887.                 thePropertyValue.GetRect(theWindowRect);
  2888.                 SetFrame(VRect(theWindowRect), TRUE);
  2889.             }
  2890.             break;
  2891.  
  2892.         case pName:
  2893.             {
  2894.                 CStr255 theWindowName;
  2895.                 thePropertyValue.GetString(theWindowName);
  2896.                 SetTitle(theWindowName);
  2897.             }
  2898.             break;
  2899.  
  2900.         case pIsZoomed:
  2901.             {
  2902.                 CRect aGDScreenRect;
  2903.                 GetMaxIntersectedDevice(aGDScreenRect);
  2904.                 VRect aGDScreenVRect(aGDScreenRect);
  2905.                 VRect zoomFrame;
  2906.                 GetUserStateFrame(aGDScreenVRect, zoomFrame);
  2907.                 Boolean isZoomed = (GetFrame() != zoomFrame);
  2908.                 Boolean shouldZoom = thePropertyValue.GetBoolean();
  2909.                 short partCode = 0;
  2910.                 if (shouldZoom && !isZoomed)
  2911.                     partCode = inZoomOut;
  2912.                 else if (!shouldZoom && isZoomed)
  2913.                     partCode = inZoomIn;
  2914.                 if (partCode != 0)
  2915.                     Zoom(partCode);
  2916.                 break;
  2917.             }
  2918.  
  2919.         case pHasCloseBox:
  2920.         case pHasTitleBar:
  2921.         case pIsModal:
  2922.         case pIsResizable:
  2923.         case pIsZoomable:
  2924.             FailOSErr(errAECantSetReadOnly);
  2925.             break;
  2926.  
  2927.         default:
  2928.             // Users will frequently refer to the window when they mean the document. If this window
  2929.             // has a document we'll give it a crack at setting the property.
  2930.             if (fDocument)
  2931.                 fDocument->SetObjectProperty(thePropertyValue, whichProperty);
  2932.             else
  2933.                 MScriptableObject::SetObjectProperty(thePropertyValue, whichProperty);
  2934.             break;
  2935.     }
  2936. }
  2937.  
  2938. #if qAttachable
  2939.  
  2940. //----------------------------------------------------------------------------------------
  2941. // TWindow::HandleOSAEvent:
  2942. //----------------------------------------------------------------------------------------
  2943. #pragma segment MAScriptingRes
  2944.  
  2945. Boolean TWindow::HandleOSAEvent(CommandNumber aCommandNumber,
  2946.                                 TAppleEvent* message,
  2947.                                 TAppleEvent* reply)
  2948. {
  2949.     // Overridden to also give the document's script a shot at the event
  2950.     return MScriptableObject::HandleOSAEvent(aCommandNumber, message, reply) || (fDocument && fDocument->HandleOSAEvent(aCommandNumber, message, reply));
  2951. }
  2952.  
  2953. #endif // qAttachable
  2954.  
  2955. //----------------------------------------------------------------------------------------
  2956. // TWindow::DoAEMove:
  2957. //----------------------------------------------------------------------------------------
  2958. #pragma segment MAWindowNonRes
  2959.  
  2960. void TWindow::DoAEMove(TAppleEvent* message,
  2961.                        TAppleEvent* reply)
  2962. {
  2963.     CTempDesc theInsertionLoc, windowObj;
  2964.     CAEDesc insertionRec;
  2965.     DescType theType, position;
  2966.     Size paramSize;
  2967.     message->ReadParameter(keyAEInsertHere, typeInsertionLoc, theInsertionLoc);
  2968.     FailOSErr(AECoerceDesc(theInsertionLoc, typeAERecord, insertionRec));
  2969.     insertionRec.GetKeyDesc(keyAEObject, typeWildCard, windowObj);
  2970.     FailOSErr(AEGetKeyPtr(insertionRec, keyAEPosition, typeEnumeration, &theType, &position, sizeof(DescType), ¶mSize));
  2971.  
  2972.     if (position == kAEBeginning)
  2973.         Select();                                // don't support the other keys yet
  2974.  
  2975.     FailOSErr(AEDisposeDesc(insertionRec));
  2976.  
  2977.     // Return an object specifier for the window
  2978.     CTempDesc theWindowSpec;
  2979.     MakeObjectSpecifier(theWindowSpec, formName);
  2980.     reply->WriteParameter(keyAEResult, theWindowSpec);
  2981. }
  2982.  
  2983. //----------------------------------------------------------------------------------------
  2984. // TWindow::DoAEClose:
  2985. //----------------------------------------------------------------------------------------
  2986. #pragma segment MAWindowNonRes
  2987.  
  2988. void TWindow::DoAEClose(TAppleEvent* message,
  2989.                         TAppleEvent* reply)
  2990. {
  2991.     // First see if a document is to be closed.
  2992.     if (fDocument && fClosesDocument)
  2993.     // Closing the document will close any associated windows.
  2994.         fDocument->DoAEClose(message, reply);
  2995.     else
  2996.         // Close the window if it wasn't attached to a document.
  2997.         DoClose(cClose, FALSE);
  2998. }
  2999.  
  3000. //----------------------------------------------------------------------------------------
  3001. // TWindow::DoAEPrint
  3002. //----------------------------------------------------------------------------------------
  3003. #pragma segment MAWindowNonRes
  3004.  
  3005. void TWindow::DoAEPrint(TAppleEvent* message,
  3006.                         TAppleEvent* reply)
  3007. {
  3008.     Boolean wasHandled = FALSE;
  3009.  
  3010.     if (fScriptingPrintHandler)
  3011.         wasHandled = fScriptingPrintHandler->DoScriptCommand(cPrint, message, reply);
  3012.  
  3013.     if (!wasHandled)
  3014.     {
  3015.         if (fDocument)
  3016.             fDocument->HandleScriptCommand(cPrint, message, reply);
  3017.         else
  3018.             MScriptableObject::DoAEPrint(message, reply);
  3019.     }
  3020. }
  3021.  
  3022. //----------------------------------------------------------------------------------------
  3023. // TWindow::DoScriptCommand
  3024. //----------------------------------------------------------------------------------------
  3025. #pragma segment MAWindowNonRes
  3026.  
  3027. void TWindow::DoScriptCommand(CommandNumber aCommandNumber,
  3028.                               TAppleEvent* message,
  3029.                               TAppleEvent* reply)
  3030. {
  3031.     switch (aCommandNumber)
  3032.     {
  3033.         case cAEDelete:
  3034.             DoAEClose(message, reply);
  3035.             break;
  3036.  
  3037.         case cAEOpen:
  3038.         case cAESave:
  3039.         case cAECountElements:
  3040.         case cAECreateElement:
  3041.         case cAEDoObjectsExist:
  3042.             if (fDocument)
  3043.             {
  3044.                 fDocument->HandleScriptCommand(aCommandNumber, message, reply);
  3045.                 break;
  3046.             }
  3047.         // no break - drop thru!
  3048.  
  3049.         default:
  3050.             MScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
  3051.             break;
  3052.     }
  3053. }
  3054.  
  3055. //----------------------------------------------------------------------------------------
  3056. // TWindow::SetScriptingPrintHandler
  3057. //----------------------------------------------------------------------------------------
  3058. #pragma segment MAWindowNonRes
  3059.  
  3060. void TWindow::SetScriptingPrintHandler(TPrintHandler* printHandler)
  3061. {
  3062.     fScriptingPrintHandler = printHandler;
  3063. }
  3064.  
  3065. //----------------------------------------------------------------------------------------
  3066. // TWindow::ReleaseScriptingPrintHandler
  3067. //----------------------------------------------------------------------------------------
  3068. #pragma segment MAWindowNonRes
  3069.  
  3070. void TWindow::ReleaseScriptingPrintHandler(TPrintHandler* printHandler)
  3071. {
  3072.     if (fScriptingPrintHandler == printHandler)
  3073.         fScriptingPrintHandler = NULL;
  3074. }
  3075.  
  3076. #if qDrag
  3077.  
  3078. //----------------------------------------------------------------------------------------
  3079. // Drag Support
  3080. //----------------------------------------------------------------------------------------
  3081.  
  3082. //----------------------------------------------------------------------------------------
  3083. // TWindow::RegisterDroppableView
  3084. //----------------------------------------------------------------------------------------
  3085. #pragma segment MADragNonRes
  3086.  
  3087. void TWindow::RegisterDroppableView(TView* theView)
  3088. {
  3089.  
  3090. #if qDebug
  3091.     if (!HasDragManager())                        // should never get called if no Drag Manager
  3092.     {
  3093.         ProgramBreak("A TDragDropBehavior registered but the Drag Manager isn't present.");
  3094.         return;
  3095.     }
  3096. #endif
  3097.  
  3098.     // the subview list isn't created until a view registers
  3099.     if (fDroppableViewList == NULL)
  3100.     {
  3101.         fDroppableViewList = new TList;
  3102.         fDroppableViewList->IList();
  3103. #if qDebug
  3104.         fDroppableViewList->SetEltType("TView");
  3105. #endif
  3106.  
  3107.     }
  3108.  
  3109. #if qDebug
  3110.     ArrayIndex index = fDroppableViewList->GetIdentityItemNo(theView);
  3111.     if (index != 0)
  3112.     {
  3113.         // ProgramBreak("### A drag/drop view tried to register itself twice");
  3114.         return;
  3115.     }
  3116. #endif
  3117.  
  3118.     fDroppableViewList->InsertElementInOrder(&theView);// add the view to the list
  3119.  
  3120.     // Register this window with the global drag session if appropriate
  3121.     if (fDragCallbackStatus == eNotInstalled)
  3122.     {
  3123.         TDragDropSession::fgDragDropSession->RegisterDroppableWindow(this, fWMgrWindow);
  3124.         fDragCallbackStatus = eInstalled;
  3125.     }
  3126. }
  3127.  
  3128. //----------------------------------------------------------------------------------------
  3129. // TWindow::UnregisterDroppableView
  3130. //----------------------------------------------------------------------------------------
  3131. #pragma segment MADragNonRes
  3132.  
  3133. void TWindow::UnregisterDroppableView(TView* theView)
  3134. {
  3135. #if qDebug
  3136.     if (!HasDragManager())                        // should never get called if the Drag Mgr isn't present
  3137.     {
  3138.         ProgramBreak("###A drag/drop view unregistered but the Drag Manager is not present.");
  3139.         return;
  3140.     }
  3141.     FailNonObject(fDroppableViewList);            // list shouldn't be NULL if this method is called
  3142. #endif
  3143.  
  3144.     fDroppableViewList->Delete(theView);
  3145.  
  3146.     // if the behavior count went to zero, unregister the window callbacks
  3147.     if (fDroppableViewList->IsEmpty())
  3148.     {
  3149.         TDragDropSession::fgDragDropSession->UnregisterDroppableWindow(fWMgrWindow);
  3150.         fDragCallbackStatus = eNotInstalled;
  3151.     }
  3152. }
  3153.  
  3154. //----------------------------------------------------------------------------------------
  3155. // TWindow::MouseToDropTarget
  3156. //----------------------------------------------------------------------------------------
  3157. #pragma segment MADragNonRes
  3158.  
  3159. TView* TWindow::MouseToDropTarget(CDragItemIterator& dragItemIterator,
  3160.                                   const CPoint& globalMouse,
  3161.                                   VPoint& localMouse)
  3162. {
  3163.     TView * targetView = NULL;
  3164.     TView * aView = NULL;
  3165.     VPoint pointInWindow(globalMouse), aPoint;
  3166.     ArrayIndex maxIndex = fDropStatusCache->GetSize();
  3167.     short oldStatus,
  3168.     newStatus;
  3169.  
  3170.     SuperToLocal(pointInWindow);
  3171.  
  3172.     // Loop through the status list. The status list is a cache of values that
  3173.     // indicate whether or not a specific view can accept the drag.
  3174.     for (ArrayIndex index = 1; index <= maxIndex; index++)
  3175.     {
  3176.         fDropStatusCache->GetElementsAt(index, &oldStatus, 1);
  3177.         if (oldStatus != kCantReceiveDrop)
  3178.         {
  3179.             newStatus = oldStatus;
  3180.             fDroppableViewList->GetElementsAt(index, &aView, 1);
  3181.             if (newStatus == kDropStatusUnknown)
  3182.             {
  3183.                 if (!aView->GetDroppable() || !aView->IsShown() || !aView->IsEnabled())
  3184.                     newStatus = kCantReceiveDrop;
  3185.             }
  3186.  
  3187.             if (newStatus != kCantReceiveDrop)
  3188.             {
  3189.                 aPoint = pointInWindow;
  3190.                 aView->WindowToLocal(aPoint);
  3191.                 if (aView->GetVisibleExtent().Contains(aPoint))
  3192.                 {
  3193.                     if (newStatus == kDropStatusUnknown)
  3194.                         newStatus = aView->WillAcceptDrop(dragItemIterator) ? kCanReceiveDrop : kCantReceiveDrop;
  3195.  
  3196.                     if ((newStatus == kCanReceiveDrop) && (!targetView || targetView->ContainsSubView(aView)))// we've got a winner!!
  3197.                     {
  3198.                         targetView = aView;
  3199.                         localMouse = aPoint;
  3200.                     }
  3201.                 }
  3202.  
  3203.             }
  3204.             if (oldStatus != newStatus)
  3205.                 fDropStatusCache->ReplaceElementsAt(index, &newStatus, 1);// cache the new status
  3206.         }
  3207.     }
  3208.  
  3209.     return targetView;
  3210. }
  3211.  
  3212. //----------------------------------------------------------------------------------------
  3213. // TWindow::DragEnteredWindow
  3214. //----------------------------------------------------------------------------------------
  3215. #pragma segment MADragNonRes
  3216.  
  3217. void TWindow::DragEnteredWindow(CDragItemIterator&/* dragItemIterator */  )
  3218. {
  3219.  
  3220. #if qDebug
  3221.     FailNonObject(fDroppableViewList);            // list shouldn't be NULL if this method is called
  3222. #endif
  3223.  
  3224.     short viewStatus = kDropStatusUnknown;
  3225.     ArrayIndex viewListSize = fDroppableViewList->GetSize();
  3226.  
  3227.     fDropStatusCache = new TDynamicArray;
  3228.     fDropStatusCache->IDynamicArray(viewListSize, sizeof(short));
  3229.  
  3230.     // initialize the status list with kDropStatusUnknown
  3231.     for (ArrayIndex i = 0; i < viewListSize; i++)
  3232.         fDropStatusCache->InsertElementsBefore(i + 1, &viewStatus, 1);
  3233. }
  3234.  
  3235. //----------------------------------------------------------------------------------------
  3236. // TWindow::DragLeftWindow
  3237. //----------------------------------------------------------------------------------------
  3238. #pragma segment MADragNonRes
  3239.  
  3240. void TWindow::DragLeftWindow()
  3241. {
  3242.     fDropStatusCache = (TDynamicArray *)FreeIfObject(fDropStatusCache);
  3243. }
  3244.  
  3245. #endif // qDrag
  3246.  
  3247. //----------------------------------------------------------------------------------------
  3248. // GetVisRegion: 
  3249. //----------------------------------------------------------------------------------------
  3250. #pragma segment MAWindowRes
  3251.  
  3252. RgnHandle TWindow::GetVisRegion(GrafPtr theGrafPtr)
  3253. {
  3254.     RgnHandle returnVal;
  3255.  
  3256.     if (pInBeginUpdate && theGrafPtr == pInBeginUpdateWindowPtr)
  3257.     {
  3258.         returnVal = pSavedVisRegion;
  3259.  
  3260.         CPoint currentOffset(((CRect &)(*returnVal)->rgnBBox)[topLeft]);
  3261.         OffsetRgn(returnVal, -currentOffset.h + theGrafPtr->portRect.left + pSavedVisRegionOriginalOffset.h, -currentOffset.v + theGrafPtr->portRect.top + pSavedVisRegionOriginalOffset.v);
  3262.     }
  3263.     else
  3264.         returnVal = theGrafPtr->visRgn;
  3265.  
  3266.     return returnVal;
  3267. }
  3268.  
  3269. //----------------------------------------------------------------------------------------
  3270. // GetUpdateRegion: 
  3271. //----------------------------------------------------------------------------------------
  3272. #pragma segment MAWindowRes
  3273.  
  3274. RgnHandle TWindow::GetUpdateRegion(WindowPtr theWindow)
  3275. {
  3276.     RgnHandle returnVal;
  3277.  
  3278.     if (TWindow::pInBeginUpdate && theWindow == pInBeginUpdateWindowPtr)
  3279.         returnVal = pSavedUpdateRegion;
  3280.     else
  3281.         returnVal = ((WindowPeek)theWindow)->updateRgn;
  3282.  
  3283.     return returnVal;
  3284. }
  3285.  
  3286. //----------------------------------------------------------------------------------------
  3287. // GetAndLoadWDefProc: 
  3288. //----------------------------------------------------------------------------------------
  3289. #pragma segment MAWindowNonRes
  3290.  
  3291. Handle TWindow::GetAndLoadWDefProc(Handle windowDefProc)
  3292. {
  3293.     Handle returnVal = NULL;
  3294.     Handle wDefProc = (Handle)(StripLong(windowDefProc));// strip the variant code 
  3295.  
  3296.     if ((*wDefProc))                            // if Master Ptr is NULL => resource is purged
  3297.         returnVal = wDefProc;
  3298.     else
  3299.     {
  3300.         LoadResource(wDefProc);
  3301.         if (ResError() == noErr)                // only return it if the LoadResource worked
  3302.             returnVal = wDefProc;
  3303.     }
  3304.     
  3305.     return returnVal;
  3306. }
  3307.  
  3308. //----------------------------------------------------------------------------------------
  3309. // HighlightAndActivateWindow: Common code for ActivateWindow and DeactivateWindow.  Does
  3310. // actual highlighting and calling of the activate handler.
  3311. //----------------------------------------------------------------------------------------
  3312. #pragma segment MAWindowNonRes
  3313.  
  3314. void TWindow::HighlightAndActivateWindow(WindowRef theWindow,
  3315.                                          Boolean activate)
  3316. {
  3317.     if (theWindow)
  3318.     {
  3319.         if ((activate && !IsWindowHilited(theWindow)) || (!activate && IsWindowHilited(theWindow)))
  3320.             HiliteWindow(theWindow, activate);    // make the window "look" right 
  3321.  
  3322.         TWindow * theMAWindow = WMgrToWindow(theWindow);
  3323.         if (theMAWindow)
  3324.             theMAWindow->Activate(activate);
  3325.     }
  3326. }
  3327.  
  3328. //----------------------------------------------------------------------------------------
  3329. // IsGhostWindow: 
  3330. //----------------------------------------------------------------------------------------
  3331. #pragma segment MAWindowRes
  3332.  
  3333. Boolean TWindow::IsGhostWindow(WindowRef window)
  3334. {
  3335.     Boolean returnVal = FALSE;
  3336.  
  3337. #if !STRICT_WINDOWS
  3338.     if (window)
  3339.         returnVal = window == (WindowRef)LMGetGhostWindow();
  3340. #endif
  3341.  
  3342.     return returnVal;
  3343. }
  3344.  
  3345.  
  3346. //----------------------------------------------------------------------------------------
  3347. // WMgrToWindow: 
  3348. //----------------------------------------------------------------------------------------
  3349. #pragma segment MAWindowRes
  3350.  
  3351. TWindow* TWindow::WMgrToWindow(WindowRef aWindowPtr)
  3352. {
  3353.     if (gWindows)
  3354.     {
  3355.         CArrayIterator iter(gWindows);
  3356.  
  3357.         // simple linear search for now
  3358.         for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
  3359.         {
  3360.             WMgrTWindowPtr aWMgrTWindowPtr = (WMgrTWindowPtr)gWindows->ComputeAddress(i);
  3361.  
  3362.             if (aWMgrTWindowPtr->itsWindow == aWindowPtr)
  3363.                 return aWMgrTWindowPtr->itsTWindow;
  3364.         }
  3365.     }
  3366.     return NULL;
  3367. }
  3368.  
  3369. //----------------------------------------------------------------------------------------
  3370. // DeleteWindow: 
  3371. //----------------------------------------------------------------------------------------
  3372. #pragma segment MAWindowNonRes
  3373.  
  3374. void TWindow::DeleteWindow(TWindow* aWindow)
  3375. {
  3376.     if (gWindows)
  3377.     {
  3378.         CArrayIterator iter(gWindows);
  3379.  
  3380.         // simple linear search for now
  3381.         for (ArrayIndex i = iter.FirstIndex(); iter.More(); i = iter.NextIndex())
  3382.         {
  3383.             if (aWindow == ((WMgrTWindowPtr)(gWindows->ComputeAddress(i)))->itsTWindow)
  3384.             {
  3385.                 gWindows->DeleteElementsAt(i, 1);
  3386.                 return;
  3387.             }
  3388.         }
  3389.     }
  3390. }
  3391.  
  3392. //----------------------------------------------------------------------------------------
  3393. // RegisterWindow: 
  3394. //----------------------------------------------------------------------------------------
  3395. #pragma segment MAWindowNonRes
  3396.  
  3397. void TWindow::RegisterWindow(TWindow* aWindow)
  3398. {
  3399.     if (!gWindows)
  3400.     {
  3401.         gWindows = new TDynamicArray;
  3402.         gWindows->IDynamicArray(kEmptyIndex, sizeof(WMgrTWindow));
  3403.     }
  3404.  
  3405.     WMgrTWindow itsWMgrTWindow;
  3406.     itsWMgrTWindow.itsTWindow = aWindow;
  3407.     itsWMgrTWindow.itsWindow = aWindow->fWMgrWindow;
  3408.  
  3409.     gWindows->InsertElementsBefore(gWindows->GetSize() + 1, &itsWMgrTWindow, 1);
  3410. }
  3411.  
  3412. //----------------------------------------------------------------------------------------
  3413. // IsDocumentWindow: 
  3414. //----------------------------------------------------------------------------------------
  3415. #pragma segment MAWindowNonRes
  3416.  
  3417. Boolean TWindow::IsDocumentWindow(WindowRef aWindow)
  3418. // If a window is not a floater window, and is not a system window, and is not the special
  3419. // THINK environment window, then it is a document window.
  3420. {
  3421.     const short kTHINKWindowKind = 32700;
  3422.     short itsWindowKind;
  3423.  
  3424.     itsWindowKind = GetWindowKind(aWindow);
  3425.     return (!IsFloatWindow(aWindow) && !IsSystemWindow(aWindow) && (itsWindowKind < kTHINKWindowKind));
  3426. }
  3427.  
  3428. //----------------------------------------------------------------------------------------
  3429. // IsDialog: 
  3430. //----------------------------------------------------------------------------------------
  3431. #pragma segment MAWindowRes
  3432.  
  3433. Boolean TWindow::IsDialog(WindowRef window)
  3434. {
  3435.     if (window)
  3436.     {
  3437.         // When checking the window type mask off all but the 
  3438.         // bottom 3 bits, which is all we care about.
  3439.         short windowVariant = (GetWindowVariant(window) & 7);
  3440.         return (windowVariant == dBoxProc) || (windowVariant == plainDBox) || (windowVariant == altDBoxProc) || (windowVariant == movableDBoxProc);
  3441.     }
  3442.     else
  3443.         return FALSE;
  3444. }
  3445.  
  3446. //----------------------------------------------------------------------------------------
  3447. // IsFloatWindow: 
  3448. //----------------------------------------------------------------------------------------
  3449. #pragma segment MAWindowRes
  3450.  
  3451. Boolean TWindow::IsFloatWindow(WindowRef window)
  3452. {
  3453.     // A note on IsFloatWindow:
  3454.     // We only consider a window to be a floating window if it is visible.  
  3455.     // The motivation around the check for visibility is that, given the Toolbox
  3456.     // Window Manager's tendency to move visible windows to the head of WindowList,
  3457.     // there is no clean way for us to guarantee that hidden floaters will stay in
  3458.     // our floating window "layer".  Instead, the approach we take is to allow 
  3459.     // hidden floaters to be moved wherever in the window list, and we ensure that
  3460.     // they move back to the floating window layer when they are shown.  The check
  3461.     // for visibility ensures that functions that depend on the first or last
  3462.     // floating window (such as TWindow::GetBehindWindowPtr) perform as expected.
  3463.     Boolean returnVal = FALSE;
  3464.  
  3465.     if (window && IsWindowVisible(window))
  3466.     {
  3467.         TWindow * aMAWindow = WMgrToWindow(window);
  3468.         if (aMAWindow)
  3469.             returnVal = aMAWindow->fFloats;
  3470.         else
  3471.             returnVal = GetWindowKind(window) == kFloatingWindowKind;
  3472.     }
  3473.  
  3474.     return returnVal;
  3475. }
  3476.  
  3477. //----------------------------------------------------------------------------------------
  3478. // IsSystemWindow: 
  3479. //----------------------------------------------------------------------------------------
  3480. #pragma segment MAWindowRes
  3481.  
  3482. Boolean TWindow::IsSystemWindow(WindowRef window)
  3483. {
  3484.     Boolean returnVal = FALSE;
  3485.  
  3486.     const short kWorldScriptWDEF = 125;
  3487.     if (window)
  3488.     {
  3489.         short theID;
  3490.         ResType theType;
  3491.         CStr255 theName;
  3492.         GetResInfo(((WindowPeek)window)->windowDefProc, &theID, &theType, theName);
  3493.         short windowKind = GetWindowKind(window);
  3494.         returnVal = (windowKind < 0) || (theID == kWorldScriptWDEF) || (theID == kBalloonWDEFID);
  3495.     }
  3496.  
  3497.     return returnVal;
  3498. }
  3499.  
  3500. //----------------------------------------------------------------------------------------
  3501. // IsModalWindow: 
  3502. //----------------------------------------------------------------------------------------
  3503. #pragma segment MAWindowRes
  3504.  
  3505. Boolean TWindow::IsModalWindow(WindowRef window)
  3506. {
  3507.     TWindow * aMAWindow = NULL;
  3508.     Boolean result = FALSE;
  3509.  
  3510.     if (window)
  3511.     {
  3512.         if ((aMAWindow = WMgrToWindow(window)) != NULL)
  3513.             result = aMAWindow->IsModal();
  3514.         else
  3515.         {
  3516.             // according to IM 4-9 (new version), these are
  3517.             // the possible window variants for modal dialogs:
  3518.             short windowVariant = GetWindowVariant(window);
  3519.             result = (windowVariant == dBoxProc) || (windowVariant == plainDBox) || (windowVariant == altDBoxProc) || (windowVariant == movableDBoxProc);
  3520.         }
  3521.     }
  3522.  
  3523.     return result;
  3524. }
  3525.  
  3526. //----------------------------------------------------------------------------------------
  3527. // GetLastFloatingWindowPtr: 
  3528. //----------------------------------------------------------------------------------------
  3529. #pragma segment MAWindowNonRes
  3530.  
  3531. // returns the last floating window in the window list
  3532. WindowRef TWindow::GetLastFloatingWindowPtr()
  3533. {
  3534.     CWMgrIterator iter;
  3535.     WindowRef lastFloatWindowPtr = NULL;
  3536.  
  3537.     for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  3538.     {
  3539.         if (IsFloatWindow(aWindowPtr))
  3540.             lastFloatWindowPtr = aWindowPtr;
  3541.     }
  3542.  
  3543.     return lastFloatWindowPtr;
  3544. }
  3545.  
  3546. //----------------------------------------------------------------------------------------
  3547. // GetFirstFloatingWindowPtr: 
  3548. //----------------------------------------------------------------------------------------
  3549. #pragma segment MAWindowNonRes
  3550.  
  3551. // returns the first floating window in the window list
  3552. WindowRef TWindow::GetFirstFloatingWindowPtr()
  3553. {
  3554.     CWMgrIterator iter;
  3555.     WindowRef firstFloatWindowPtr = NULL;
  3556.  
  3557.     for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More() && (firstFloatWindowPtr == NULL); aWindowPtr = iter.NextWMgrWindow())
  3558.     {
  3559.         if (IsFloatWindow(aWindowPtr))
  3560.             firstFloatWindowPtr = aWindowPtr;
  3561.     }
  3562.  
  3563.     return firstFloatWindowPtr;
  3564. }
  3565.  
  3566. //----------------------------------------------------------------------------------------
  3567. // ActivateWindow: Activates the window by highlighting it, and calling its
  3568. // activate handler.
  3569. //----------------------------------------------------------------------------------------
  3570. #pragma segment MAWindowNonRes
  3571.  
  3572. void TWindow::MAActivateWindow(WindowRef theWindow)
  3573. {
  3574.     HighlightAndActivateWindow(theWindow, kActivateWindow);
  3575. }
  3576.  
  3577. //----------------------------------------------------------------------------------------
  3578. // DeactivateWindow: Deactivates the window by unhighlighting it and calling its
  3579. // activate handler.
  3580. //----------------------------------------------------------------------------------------
  3581. #pragma segment MAWindowNonRes
  3582.  
  3583. void TWindow::MADeactivateWindow(WindowRef theWindow)
  3584. {
  3585.     HighlightAndActivateWindow(theWindow, kDeactivateWindow);
  3586. }
  3587.  
  3588. //----------------------------------------------------------------------------------------
  3589. // MADragWindow: Our replacement for DrawWindow to handle floating windows…
  3590. //----------------------------------------------------------------------------------------
  3591. #pragma segment MAWindowNonRes
  3592.  
  3593. void TWindow::MADragWindow(WindowRef windowToDrag,
  3594.                            CPoint startPoint,
  3595.                            const CRect& draggingBounds)
  3596. {
  3597.     CRect dragRect;
  3598.     GrafPtr savePort;
  3599.     GrafPtr windowManagerPort;
  3600.     long dragResult;
  3601.     short topLimit;
  3602.     short newHorizontalWindowPosition;
  3603.     short newVerticalWindowPosition;
  3604.     short horizontalOffset;
  3605.     short verticalOffset;
  3606.     Boolean commandKeyDown = FALSE;
  3607.  
  3608.     if (WaitMouseUp())
  3609.     {
  3610.         // Adjust the top of the dragging rectangle so that it’s below the menu bar
  3611.         topLimit = GetMBarHeight() + 4;
  3612.         dragRect = draggingBounds;
  3613.         if (dragRect.top < topLimit)
  3614.             dragRect.top = topLimit;
  3615.  
  3616.         // Set up the Window Manager port.
  3617.         GetPort(&savePort);
  3618.         GetWMgrPort(&windowManagerPort);
  3619.         SetPort(windowManagerPort);
  3620.         SetClip(GetGrayRgn());
  3621.  
  3622.         commandKeyDown = IsCommandKeyDown();
  3623.  
  3624.         if (commandKeyDown || !(IsFloatWindow(windowToDrag) || IsModalWindow(windowToDrag)))
  3625.         {
  3626.             if (!commandKeyDown)
  3627.             {
  3628.                 // If there are floating windows, clip the dragging outline to draw
  3629.                 // behind the floaters.
  3630.                 ClipAbove(MAFrontWindow());
  3631.             }
  3632.             else
  3633.             {
  3634.                 // If the command key was down, clip the outline to draw behind any
  3635.                 // windows above the window being dragged.
  3636.                 ClipAbove(windowToDrag);
  3637.             }
  3638.         }
  3639.  
  3640.         // Create a region to drag
  3641.         CTemporaryRegion dragRegion;
  3642.  
  3643.         GetWindowStructureRgn(windowToDrag, dragRegion);
  3644.  
  3645.         // Drag the window around
  3646.         dragResult = DragGrayRgn(dragRegion, startPoint, &dragRect, &dragRect, noConstraint, NULL);
  3647.  
  3648.         // Restore the port for coordinate conversion.
  3649.         SetPort(savePort);
  3650.  
  3651.         if (dragResult != 0)
  3652.         {
  3653.             horizontalOffset = (short)(dragResult & 0xFFFF);
  3654.             verticalOffset = (short)(dragResult >> 16);
  3655.  
  3656.             // Only move it if it stayed inside the dragging box.
  3657.             if (verticalOffset != -32768)
  3658.             {
  3659.                 CTemporaryRegion contRgn;
  3660.                 GetWindowContentRgn(windowToDrag, contRgn);
  3661.  
  3662.                 newHorizontalWindowPosition = (*contRgn)->rgnBBox.left + horizontalOffset;
  3663.                 newVerticalWindowPosition = (*contRgn)->rgnBBox.top + verticalOffset;
  3664.  
  3665.                 MoveWindow(windowToDrag, newHorizontalWindowPosition, newVerticalWindowPosition, FALSE);
  3666.             }
  3667.         }
  3668.  
  3669.         // Bring the window forward if the command key wasn’t down
  3670.         if (!commandKeyDown)
  3671.             MASelectToolboxWindow(windowToDrag);// 3.5
  3672.     }
  3673. }
  3674.  
  3675. // Added for 3.5:
  3676. //----------------------------------------------------------------------------------------
  3677. // MASelectToolboxWindow: 
  3678. //----------------------------------------------------------------------------------------
  3679. #pragma segment MAApplicationRes
  3680.  
  3681. void TWindow::MASelectToolboxWindow(WindowRef windowToSelect)
  3682. {
  3683.     WindowRef currentFrontWindow = NULL;
  3684.     WindowRef lastFloatingWindow = NULL;
  3685.     Boolean isFloatingWindow = IsFloatWindow(windowToSelect);
  3686.  
  3687.     if (isFloatingWindow)
  3688.     {
  3689.         currentFrontWindow = GetFirstFloatingWindowPtr();
  3690.     }
  3691.     else
  3692.     {
  3693.         currentFrontWindow = MAFrontWindow();
  3694.         lastFloatingWindow = GetLastFloatingWindowPtr();
  3695.     }
  3696.  
  3697.     // Be fast (and lazy) and do nothing if we don’t have to.
  3698.     if (currentFrontWindow != windowToSelect)
  3699.     {
  3700.         // Selecting floating windows are easy, since they’re always active
  3701.         if (isFloatingWindow)
  3702.             BringToFront(windowToSelect);
  3703.         else
  3704.         {
  3705.             // If there are no floating windows, we can call SelectWindow like the good ol’ days
  3706.             if (lastFloatingWindow == NULL)
  3707.             {
  3708.                 //SRF
  3709.                 // Keep control off Window's control list b/c the Window Mgr adds the regions of controls in
  3710.                 // the control list to the update region (see NOTE under DrawControls in Inside Mac volume I)
  3711.                 // generating an update event and causing all controls in a window to redraw unnecessarily.
  3712.  
  3713.                 ControlHandle oldFrontControlList;
  3714.                 ControlHandle newFrontControlList;
  3715. #if STRICT_WINDOWS
  3716.                 if (currentFrontWindow)
  3717.                 {
  3718.                     oldFrontControlList = GetControlOwningWindowControlList(currentFrontWindow);
  3719.                     GetControlOwningWindowControlList(currentFrontWindow) = NULL;
  3720.                 }
  3721.  
  3722.                 newFrontControlList = GetControlOwningWindowControlList(windowToSelect);
  3723.                 GetControlOwningWindowControlList(windowToSelect) = NULL;
  3724. #else
  3725.                 if (currentFrontWindow)
  3726.                 {
  3727.                     oldFrontControlList = ((WindowPeek)currentFrontWindow)->controlList;
  3728.                     ((WindowPeek)currentFrontWindow)->controlList = NULL;
  3729.                 }
  3730.  
  3731.                 newFrontControlList = ((WindowPeek)windowToSelect)->controlList;
  3732.                 ((WindowPeek)windowToSelect)->controlList = NULL;
  3733. #endif
  3734.  
  3735.                 SelectWindow(windowToSelect);
  3736.  
  3737. #if STRICT_WINDOWS
  3738.                 if (currentFrontWindow)
  3739.                     GetControlOwningWindowControlList(currentFrontWindow) = oldFrontControlList;
  3740.  
  3741.                 GetControlOwningWindowControlList(windowToSelect) = newFrontControlList;
  3742. #else
  3743.                 if (currentFrontWindow)
  3744.                     ((WindowPeek)currentFrontWindow)->controlList = oldFrontControlList;
  3745.  
  3746.                 ((WindowPeek)windowToSelect)->controlList = newFrontControlList;
  3747. #endif
  3748.  
  3749.             }
  3750.             else
  3751.             {
  3752.                 // Deactivate the window currently in front.
  3753.                 MADeactivateWindow(currentFrontWindow);
  3754.  
  3755.                 // Bring it behind the last floating window if it is not modal and activate it.
  3756.                 // Note that Inside Mac 1 states that you need to call PaintOne() and CalcVis() on a
  3757.                 // window if you are using SendBehind() to bring it closer to the front.  With System 7,
  3758.                 // this is no longer necessary.
  3759.  
  3760.                 if (!(IsModalWindow(windowToSelect)))
  3761.                     SendBehind(windowToSelect, lastFloatingWindow);
  3762.                 else
  3763.                     BringToFront(windowToSelect);
  3764.  
  3765.                 MAActivateWindow(windowToSelect);
  3766.             }
  3767.         }
  3768.     }
  3769.  
  3770.     // Make sure previous mouse clicks are not considered part of a multi-click.
  3771.     gDispatcher->fLastClickPart = inDesk;
  3772. }
  3773. // End added for 3.5
  3774.  
  3775. //----------------------------------------------------------------------------------------
  3776. // MAShowWindow: Show the specified window.  If the window is the frontmost document
  3777. // window, unhighlight the window behind it, deactivate it, and activate this one.
  3778. //----------------------------------------------------------------------------------------
  3779. #pragma segment MAWindowNonRes
  3780.  
  3781. void TWindow::MAShowWindow(WindowRef windowToShow)
  3782. {
  3783.     enum WindowFoundState
  3784.     {
  3785.         eWindowNotFound, eWindowIsFrontmost, eWindowIsNotFrontmost
  3786.     };
  3787.  
  3788.  
  3789.     WindowRef frontNonFloatingNonModalWindow = NULL;
  3790.     Boolean windowIsInFront = FALSE;
  3791.  
  3792.     if (!IsWindowVisible(windowToShow))
  3793.     {
  3794.         frontNonFloatingNonModalWindow = MAFrontWindow();
  3795.  
  3796.         if (IsFloatWindow(windowToShow))
  3797.         {
  3798.             // A floating window is being shown.  Check to see if a modal window is up before
  3799.             // allowing the floater to receive activates.
  3800.             windowIsInFront = !IsModalWindow(FrontWindow());
  3801.         }
  3802.         else
  3803.         {
  3804.             if (IsModalWindow(windowToShow))
  3805.             {
  3806.                 // We are bringing up a modal window! If we are bringing it up in front of
  3807.                 // another modal window, we need to deactivate that one.  Otherwise we need
  3808.                 // to make sure that the frontNonFloatingNonModalWindow has been deactivated…
  3809.                 CWMgrIterator iter;
  3810.                 WindowFoundState windowToShowFoundState = eWindowNotFound;
  3811.  
  3812.                 for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More() && (windowToShowFoundState == eWindowNotFound); aWindowPtr = iter.NextWMgrWindow())
  3813.                 {
  3814.                     if (aWindowPtr == windowToShow)
  3815.                         windowToShowFoundState = eWindowIsFrontmost;
  3816.                     else if (IsWindowVisible(aWindowPtr))
  3817.                         windowToShowFoundState = (IsModalWindow(aWindowPtr) ? eWindowIsNotFrontmost : eWindowIsFrontmost);
  3818.                 }
  3819.  
  3820.                 if (windowToShowFoundState == eWindowIsFrontmost)
  3821.                 {
  3822.                     windowIsInFront = TRUE;
  3823.  
  3824.                     // now deactivate the frontmost modal window or nonfloater, whichever comes first…
  3825.                     WindowRef theWnd = FrontWindow();
  3826.                     if (theWnd)
  3827.                     {
  3828.                         if (IsModalWindow(theWnd))
  3829.                             MADeactivateWindow(theWnd);
  3830.                         else
  3831.                             MADeactivateWindow(frontNonFloatingNonModalWindow);
  3832.                     }
  3833.                 }
  3834.             }
  3835.             else
  3836.             {
  3837.                 // We are showing a non-floater, non-modal window.  If it is in front of the
  3838.                 // frontNonFloatingNonModalWindow, we need a deactivate…
  3839.  
  3840.                 if (frontNonFloatingNonModalWindow == NULL)
  3841.                     windowIsInFront = TRUE;
  3842.                 else
  3843.                 {
  3844.                     CWMgrIterator iter;
  3845.                     WindowFoundState windowToShowFoundState = eWindowNotFound;
  3846.  
  3847.                     for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More() && (windowToShowFoundState == eWindowNotFound); aWindowPtr = iter.NextWMgrWindow())
  3848.                     {
  3849.                         if (aWindowPtr == windowToShow)
  3850.                             windowToShowFoundState = eWindowIsFrontmost;
  3851.                         else if (aWindowPtr == frontNonFloatingNonModalWindow)
  3852.                             windowToShowFoundState = eWindowIsNotFrontmost;
  3853.                     }
  3854.  
  3855.                     if (windowToShowFoundState == eWindowIsFrontmost)
  3856.                     {
  3857.                         windowIsInFront = TRUE;
  3858.                         MADeactivateWindow(frontNonFloatingNonModalWindow);
  3859.                     }
  3860.                 }
  3861.             }
  3862.         }
  3863.  
  3864.         if (windowIsInFront || IsFloatWindow(windowToShow))
  3865.         {
  3866.             // Set the highlight state so the window appears highlighted from the start.
  3867.             HiliteWindow(windowToShow, TRUE);
  3868.         }
  3869.  
  3870.         // Show the window
  3871.         ShowHide(windowToShow, TRUE);
  3872.  
  3873.         // If this is the new frontmost document window or a floating window, send it an activate event
  3874.         if (windowIsInFront)
  3875.         {
  3876.             TWindow * theMAWindow = NULL;
  3877.             if ((theMAWindow = WMgrToWindow(windowToShow)) != NULL)
  3878.             {
  3879.                 theMAWindow->Activate(TRUE);
  3880.             }
  3881.         }
  3882.     }
  3883. }
  3884.  
  3885. //----------------------------------------------------------------------------------------
  3886. // MAHideWindow: Hide the specified window.
  3887. //----------------------------------------------------------------------------------------
  3888. #pragma segment MAWindowNonRes
  3889.  
  3890. void TWindow::MAHideWindow(WindowRef windowToHide)
  3891. {
  3892.     Boolean needToActivateAnotherWindow = FALSE;
  3893.  
  3894.     // Don’t do anything if the window is already invisible.
  3895.     if (IsWindowVisible(windowToHide))
  3896.     {
  3897.         needToActivateAnotherWindow = IsWindowHilited(windowToHide) && !IsFloatWindow(windowToHide);
  3898.  
  3899.         // Give the window a change of deactivating in case it is presently active…
  3900.         MADeactivateWindow(windowToHide);
  3901.  
  3902.         // Hide the window.
  3903.         ShowHide(windowToHide, FALSE);
  3904.  
  3905.         // if we were hiding the active window (it was either the frontmost nonfloater or the
  3906.         // frontmost modal window), we need to find and activate another window…
  3907.         if (needToActivateAnotherWindow)
  3908.         {
  3909.             WindowRef windowToActivate = FrontWindow();
  3910.             while (windowToActivate && (IsFloatWindow(windowToActivate) || !IsWindowVisible(windowToActivate)))
  3911.                 windowToActivate = GetNextWindow(windowToActivate);
  3912.  
  3913.             // if we found one, activate it!
  3914.             if (windowToActivate != NULL)
  3915.                 MAActivateWindow(windowToActivate);
  3916.         }
  3917.     }
  3918. }
  3919.  
  3920.  
  3921. //----------------------------------------------------------------------------------------
  3922. // MAFrontWindow: 
  3923. //----------------------------------------------------------------------------------------
  3924. #pragma segment MAWindowRes
  3925.  
  3926. // Returns the first visible, non-floater window in the window list. Ignores the ghost window (if any). 
  3927. // Note that if a modal window has been brought up in front of the floaters, we bypass it too.
  3928. WindowRef TWindow::MAFrontWindow()
  3929. {
  3930.     WindowRef returnVal = NULL;
  3931.  
  3932.     CWMgrIterator iter;
  3933.  
  3934.     for (WindowRef aWindowPtr = iter.FirstWMgrWindow(); iter.More(); aWindowPtr = iter.NextWMgrWindow())
  3935.     {
  3936.         if (!(IsFloatWindow(aWindowPtr) || IsGhostWindow(aWindowPtr) || IsSystemWindow(aWindowPtr) || IsModalWindow(aWindowPtr)) && IsWindowVisible(aWindowPtr))
  3937.         {
  3938.             returnVal = aWindowPtr;
  3939.             break;
  3940.         }
  3941.     }
  3942.  
  3943.     return returnVal;
  3944. }
  3945.  
  3946. //----------------------------------------------------------------------------------------
  3947. // FreeIfWMgrWindow: 
  3948. //----------------------------------------------------------------------------------------
  3949. #pragma segment MAWindowRes
  3950.  
  3951. WindowRef TWindow::FreeIfWMgrWindow(WindowRef w,
  3952.                                     Boolean dispose)
  3953. {
  3954.     if (w)
  3955.     {
  3956.         // If the window is visible, hide it first so
  3957.         // that the proper activate and deactivate events are sent.
  3958.         if (IsWindowVisible(w))
  3959.             MAHideWindow(w);
  3960.  
  3961.         if (dispose)
  3962.         {
  3963.             if (GetWindowPort(w) == (CGrafPtr)qd.thePort)// Only need to invalidate focus if freed window is the current port
  3964.             {
  3965.                 if (gDispatcher)
  3966.                     gDispatcher->InvalidateFocus();
  3967.                 SetPortWindowPort(gWorkPort);
  3968.             }
  3969.             DisposeWindow(w);
  3970.         }
  3971.         else
  3972.             CloseWindow(w);
  3973.     }
  3974.     return NULL;                                // convenience to caller 
  3975. }
  3976.  
  3977. //----------------------------------------------------------------------------------------
  3978. // End of UWindow.cp
  3979.  
  3980. #pragma segment Inline
  3981.  
  3982.